Skip to content
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

Code rewrite for Julia v0.6 #113

Closed
26 tasks done
andyferris opened this issue Feb 26, 2017 · 12 comments
Closed
26 tasks done

Code rewrite for Julia v0.6 #113

andyferris opened this issue Feb 26, 2017 · 12 comments

Comments

@andyferris
Copy link
Member

andyferris commented Feb 26, 2017

Much of the code needs revamping for Jula v0.6 (see e.g. #109). I've made a start on the julia-0.6 branch, but more work remains. This is a tracking issue.

The requirement is to replace all calls to size (or Size) from within a @generated function generator to outside of the generator, such as in the generated body, or by using an outer function which calls Size and another @generated one which unrolls expressions, etc (given the relevant sizes as an input).

Here's a list of all the files/remaining tasks. Completed files should use v0.6 syntax/dispatch rules/etc (no Compat):

  • util.jl
  • traits.jl
  • convert.jl (previously was core.jl)
  • SUnitRange.jl (this is new)
  • Scalar.jl
  • SVector.jl
  • FieldVector.jl
  • SMatrix.jl
  • SArray.jl
  • MVector.jl
  • MMatrix.jl
  • MArray.jl
  • SizedArray.jl
  • abstractarray.jl
  • indexing.jl (now more generic indexing that implements all the APL rules)
  • broadcast.jl (new file, now generalized to arbitrarily many inputs)
  • mapreduce.jl
  • arraymath.jl
  • linalg.jl
  • matrix_multiply.jl
  • solve.jl
  • deque.jl
  • det.jl
  • inv.jl
  • eigen.jl
  • cholesky.jl
@andyferris
Copy link
Member Author

In the branch I made it so that similar_type always defaults to an immutable array like SVector unless the user specifies. This lets you e.g. make really fast code from getindex(::AbstractVector, ::StaticVector) -> SVector, which is kind-of useful I imagine. Algorithms which demand mutability should definitely use similar (and we'd better check what copy does - you only need a copy of something which mutates...).

Any feedback on this decision?

@timholy
Copy link
Member

timholy commented Feb 27, 2017

That seems very reasonable to me. Thanks for tackling this! I'd plunge in to help except that I'm a little swamped by other things (among other things, I've been working for nearly 2 weeks on trying to get the JuliaImages organization packages working on 0.6), but if you have difficult design choices don't hesitate to ask.

@andyferris
Copy link
Member Author

That's OK Tim - the brainstorming was very useful to me :)

@andreasnoack
Copy link
Member

You might already be on top on this but the promotion mechanism in

S = typeof((one(T)*zero(T) + zero(T))/one(T))
is also broken after the 265 fix. I'm not sure what the right fix is. Small example

julia> using StaticArrays

julia> using ForwardDiff

julia> function foo()
         x = @SMatrix zeros(ForwardDiff.Dual{0,Float64}, 3, 3)
         y = @SVector zeros(ForwardDiff.Dual{0,Float64}, 3)
         x\y
       end
foo (generic function with 1 method)

julia> foo()
ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type ForwardDiff.Dual{0,Float64}
The applicable method may be too new: running in world age 21498, while current world is 21504.
This may have arisen from a call to the constructor ForwardDiff.Dual{0,Float64}(...),
since type constructors fall back to convert methods.
Stacktrace:
 [1] zero(::Type{ForwardDiff.Dual{0,Float64}}) at ./number.jl:131
 [2] zeros(::Type{T} where T, ::Int64, ::Int64) at ./array.jl:252
 [3] zeros(...) at /Users/andreasnoack/.julia/v0.6/StaticArrays/src/arraymath.jl:82
 [4] foo() at ./REPL[3]:2

@andyferris
Copy link
Member Author

Thanks. That's ok, it's easy to put the newtype calculation into the generated body.

@KristofferC
Copy link
Contributor

KristofferC commented Mar 6, 2017

Are there any reason why the reductions are using @generated?

For example:

@inline function reduce(op, v0, a::StaticArray)
    if length(a) == 0
        return v0
    else
        s = v0
        @inbounds @simd for j = 1:length(a)
            s = op(s, a[j])
        end
        return s
    end
end

unrolls to the same code as the generated one when the array is small enough but also transitions to SIMD when LLVM thinks it is necessary. sum and company does not get to enjoy this however due to JuliaLang/julia#20913...

@andyferris
Copy link
Member Author

andyferris commented Mar 6, 2017

Are there any reason why the reductions are using @generated?

The answer would be "magical thinking" - or more precisely, making assumptions rather than measuring things. :)

I bet this case is particularly dependent on eltype as well. If you throw in a Dual or a Complex or a StaticArray{<:StaticArray} you might see the tables turn. I'm not sure. It would be damn useful to know how and when LLVM decides to vectorize things...

@andyferris
Copy link
Member Author

andyferris commented Mar 9, 2017

I've fixed the strange slowdown here, @c42f. It turned out that getindex and setindex! were a bit funny - it no longer causes long delays for me (though I don't see why it should have originally).

@andyferris
Copy link
Member Author

Last "hard" file will be matrix_multiply.jl. Getting closer...

@tkoolen
Copy link
Contributor

tkoolen commented Mar 13, 2017

Thank you so much for your effort! My package would be dead without StaticArrays!

@andyferris
Copy link
Member Author

Yes, many of ours too...

@andyferris
Copy link
Member Author

Done! :) Follow #121 for updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants