- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.7k
StridedArray->AbstractArray in many places #15367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|  | ||
| @test_throws ErrorException transpose(sub(sprandn(10, 10, 0.3), 1:4, 1:4)) | ||
| @test_throws ErrorException ctranspose(sub(sprandn(10, 10, 0.3), 1:4, 1:4)) | ||
|  | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it's always scary to delete tests, I wasn't sure why this was something that needed testing. On this branch,
julia> A = sub(sprandn(10, 10, 0.3), 1:4, 1:4)
4x4 SubArray{Float64,2,SparseMatrixCSC{Float64,Int64},Tuple{UnitRange{Int64},UnitRange{Int64}},false}:
 0.0  0.0      -1.41166    0.0    
 0.0  0.0       0.0        0.0    
 0.0  0.0       0.628624   1.40626
 0.0  1.08286   0.0       -0.97074
julia> transpose(A)
4x4 sparse matrix with 5 Float64 entries:
        [3, 1]  =  -1.41166
        [3, 3]  =  0.628624
        [4, 3]  =  1.40626
        [2, 4]  =  1.08286
        [4, 4]  =  -0.97074
julia> full(transpose(A))
4x4 Array{Float64,2}:
  0.0      0.0  0.0        0.0    
  0.0      0.0  0.0        1.08286
 -1.41166  0.0  0.628624   0.0    
  0.0      0.0  1.40626   -0.97074which seems like a rather satisfactory result. (It's even sparse!)
CC @kshyatt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how does it perform relative to the non subarray sparse transpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and could this be changed to an affirmative test now that it works?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't tested, but I'm sure it's dreadful. We need a good iterator for sparse matrices and their views.
| @jrevels, any idea about the Nanosoldier error? | 
| Really nice! | 
| The fixed bug with a wrapper AbstractArray type should be tested for, no? | 
| Let's try again and see if it magically works this time: | 
This allows us to defer the definition of StridedArray until much later in the bootstrap process.
| 
 Sorry about the delay, I've been battling the flu. Let's see if the patch I just pushed fixed things: 
 | 
87cfcb4    to
    1982118      
    Compare
  
    | Sorry to hear about the flu! Hope you're winning the battle! I think I discovered the problem: sparse matrix multiplication was dispatching differently. I added another commit to fix that. Can we cancel the run you started and try fresh? | 
| When we launch it, I guess we probably want  | 
| 
 | 
| Hmm. Looks like the tag predicate validation is wonky now. I'll look into it. | 
| I should add that I've run the sparse tests locally, and things look fine. I'm launching a run with the full  | 
| Appreciated. Though it's difficult to rest when there are bugs afoot! Let's give it one last shot: 
 | 
| Am I correct that the goal here is to delay the definition of  I spotted that  | 
| 
 I noticed that too. My view is, one MethodError is as good as another MethodError. Now  
 I've given some thought to defining  for jblk in 1:skipj:size(A,d1)  # d1 is the dimension that is fastest in the permuted array B
    for iblk in 1:skipi:size(A,1)
        for j in jblk:min(jblk+skipj-1, size(A,d1))
            for i in iblk:min(iblk+skipi-1, size(A,1))
                B[j,IB1,i,IB2] = A[i,IA1,j,IA2]
 end end end endwhere all the  Might be a good "up for grabs" issue. | 
| Oh, and forgot to respond to 
 Delaying is part of the goal, but not the only one. Our multiplication routine, for example, is general, yet we get the error at the top. In general, I suspect we've been using  | 
| 
 Any kind of distributed array is also doomed when you start elementwise indexing. It is already a problem to the extent that during the development cycle, I don't make any kind of distributed array a subtype of  I'm sure you have mentioned it somewhere before, but why is it that your arrays cannot be considered  | 
| Sure, I completely agree that some types won't be efficient, and that this is a genuine problem. But that's true for many algorithms not among the ones I modified: try calling  AFAICT, in the functions I modified, with the exception of  Since essentially none of the algorithms required strides, dispatching on  type ProductMatrix{T} <: AbstractMatrix{T}
    xrange::StepRange{T,T}
    yrange::StepRange{T,T}
end
Base.getindex(A::ProductArray, i, j) = A.xrange[i]*A.yrange[j]Definitely not a  I'm simply of the growing belief that things should work first and foremost, and be efficient secondarily. If one needs a more efficient version of an algorithm, one should write it, but we shouldn't make people re-implement all of array arithmetic simply because we were worried that the generic algorithm might be slow for a subset of types. | 
| Your benchmark job has completed, but something went wrong when trying to upload the result data. cc @jrevels EDIT: I forgot to turn off a debug flag I was using when messing with the report uploading code...oops. Here are the results -- Jarrett 
 | 
| While the nanosoldier benchmark didn't work out, it's not worth trying again: I've run the benchmarks on my local machine, and there are no reproducible regressions. For the record, when nanosoldier errors out, it's definitely worth looking into: without 1982118, because of the change in dispatch priority this would have had massive performance regressions for sparse matrix multiplication. ("...janitorial changes have a nasty habit of generating unexpected performance regressions" is a lesson learned the hard way.) I'll leave this open longer to ensure that any concerns have been addressed. | 
| I agree with @timholy. Generic definitions should accept any  | 
| Thanks, @jrevels! | 
| 
 Above, I argued for the opposite. It is actually pretty useful when you try to exploit the structure of a type. I'm okay with this change since it is consistent and will probably give a lot of users fewer error messages, but I wanted to point out that methods that extract each element of  | 
| 
 Sorry, but I don't understand what a  
 You could easily write it even if the fallback exists, so what's the problem? | 
| 
 Getting the  | 
| I see. With protocols/traits, it would be easy to list which all methods that the type needs to support and show for each whether it uses the  | 
| That's an interesting and quite intriguing development strategy, I'd never thought of that before. I expect that the debugger will change the calculus a lot, since it will be much easier to step in and see what gets called. In other words, even though it's useful from the standpoint of someone writing the library, I doubt we want such considerations to affect how we architect the standard library from a user perspective. | 
| There are certainly some types where you'd want fallback methods to be noticeable via warnings or errors in some debug/development/noisy configurations, but I think the default behavior should be to do the correct thing rather than error even if it's slow. Especially if the slowness is fixable - but to fix it someone has to be aware of it first. | 
StridedArray->AbstractArray in many places
This is a largely janitorial change that allows us to defer the definition of
StridedArrayuntil much later in the bootstrap process. This was motivated by my (still unfinished) work onReshapedArrays, but this appears to have some value on its own merits: now that we have nice iterators and indexing, "strides" simply aren't a very important concept anymore for pure julia code. So the usage ofStridedArrayshould generally be limited to interactions with outside libraries that require strided data layout.This also fixes a bug (currently on master):
immutable MyArray{T,N} <: AbstractArray{T,N} data::Array{T,N} end Base.size(A::MyArray) = size(A.data) Base.getindex(A::MyArray, indexes...) = A.data[indexes...] A = MyArray(rand(4,5)) b = rand(5) julia> A*b ERROR: LoadError: MethodError: no method matching A_mul_B!(::Array{Float64,1}, ::MyArray{Float64,2}, ::Array{Float64,1}) Closest candidates are: ...The most important reason I decided to submit this separately is that janitorial changes have a nasty habit of generating unexpected performance regressions, so I wanted to
runbenchmarks("array", vs = "JuliaLang/julia:master").