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

Type-unstable code in Julia master #321

Closed
giordano opened this issue Oct 16, 2017 · 4 comments
Closed

Type-unstable code in Julia master #321

giordano opened this issue Oct 16, 2017 · 4 comments

Comments

@giordano
Copy link

giordano commented Oct 16, 2017

This code:

const d_lng = SVector(0, -2, 0, 0, 0, 0, -2, 0, 0, -2, -2, -2, 0, 2, 0, 2, 0, 0, -2, 0,
                      2, 0, 0, -2, 0, -2, 0, 0, 2,  -2, 0, -2, 0, 0, 2, 2, 0, -2, 0, 2,
                      2, -2, -2, 2, 2, 0, -2, -2, 0, -2, -2, 0, -1, -2, 1, 0, 0, -1, 0,
                      0,  2, 0, 2)
const M_lng = SVector(0, 0, 0, 0, 1, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                      0, 0, 0, 0, 0, 0, 2, 0, 2, 1, 0, -1, 0, 0, 0, 1, 1, -1, 0, 0, 0,
                      0, 0, 0, -1, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 1, -1, -1, 0,
                      -1)
const Mprime_lng = SVector(0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, -1, 0, 1, -1, -1, 1, 2,
                           -2, 0, 2, 2, 1, 0, 0, -1, 0, -1,  0, 0, 1, 0, 2, -1, 1, 0,
                           1, 0, 0, 1, 2, 1, -2, 0, 1, 0, 0, 2, 2, 0, 1, 1, 0, 0, 1,
                           -2, 1, 1, 1, -1, 3, 0)
const F_lng = SVector(0, 2, 2, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, 0, 0, 2, 0, 2, 0, 2, 2, 2,
                      0, 2, 2, 2, 2, 0, 0, 2, 0, 0,  0, -2, 2, 2, 2, 0, 2, 2, 0, 2, 2,
                      0, 0, 0, 2, 0, 2, 0, 2, -2, 0, 0, 0, 2, 2, 0, 0, 2, 2, 2, 2)
const ω_lng = SVector(1, 2, 2, 2, 0, 0, 2, 1, 2, 2, 0, 1, 2, 0, 1, 2, 1, 1, 0, 1, 2, 2,
                      0, 2, 0, 0, 1, 0, 1, 2, 1, 1, 1, 0, 1, 2, 2, 0, 2, 1, 0, 2, 1, 1,
                      1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 2, 2)

function nutate(jd::AbstractFloat)
    d = 1.0
    M = 2.0
    Mprime = 3.0
    F = 5.0
    ω = 4.0
    arg = @. d_lng * d + M_lng * M + Mprime_lng * Mprime + F_lng * F + ω_lng * ω
end

results in a type-unstable function on Julia master:

julia> @code_warntype nutate(2.4e6)
Variables:
  jd<optimized out>
  #1::getfield(Main, Symbol("##1#2"))
  d<optimized out>
  M<optimized out>
  Mprime<optimized out>
  F<optimized out>
  ω<optimized out>
  arg<optimized out>

Body:
  begin
      #= line 7 =#
      #1::getfield(Main, Symbol("##1#2")) = $(Expr(:new, :(Main.##1#2)))
      # meta: location broadcast.jl broadcast 434
      # meta: location /home/mose/.julia/v0.7/StaticArrays/src/broadcast.jl broadcast_c 33
      SSAValue(6) = (Core._apply)(Core.tuple, (Size(63,),), $(Expr(:invoke, MethodInstance for broadcast_sizes(::Float64, ::SVector{63,Int64}, ::Vararg{Any,N} where N), :(StaticArrays.broadcast_sizes), 1.0, :(Main.M_lng), 2.0, :(Main.Mprime_lng), 3.0, :(Main.F_lng), 5.0, :(Main.ω_lng), 4.0))::Tuple{StaticArrays.Size{()},StaticArrays.Size{(63,)},Vararg{Any,N} where N})::Tuple{StaticArrays.Size{(63,)},StaticArrays.Size{()},StaticArrays.Size{(63,)},Vararg{Any,N} where N}
      # meta: pop locations (2)
      SSAValue(5) = (StaticArrays._broadcast)(#1::getfield(Main, Symbol("##1#2")), SSAValue(6), Main.d_lng, 1.0, Main.M_lng, 2.0, Main.Mprime_lng, 3.0, Main.F_lng, 5.0, Main.ω_lng, 4.0)::Any
      return SSAValue(5)
  end::Any

Instead, everything is fine in Julia 0.6. The function is type-stable if the value of arg is replaced by:

@. d_lng * 1.0 + M_lng * 2.0 + Mprime_lng * 3.0 + F_lng * 4.0 + ω_lng * 5.0

It is stable also with

@. d_lng * d + M_lng * M
@c42f
Copy link
Member

c42f commented Oct 17, 2017

This code has probably fallen victim of some of the inference heuristics - so perhaps there's not much which can be done about it in StaticArrays. It bears investigation though (what is the minimal working example?)

What happens when you simply remove the @.:

arg = d_lng * d + M_lng * M + Mprime_lng * Mprime + F_lng * F + ω_lng * ω

Efficient StaticArrays usage generally shouldn't require explicit loop fusion as everything is unrolled anyway.

@giordano
Copy link
Author

What happens when you simply remove the @.

Ok, that does the trick, thanks!

Is it worth reporting this issue to Julia? It's quite annoying also because it's a regression, it used to work with previous versions.

@c42f
Copy link
Member

c42f commented Oct 17, 2017

It's probably worth reporting, but first worth exploring which parts you can remove until it just starts working. Eg, does it depend on the length of the SVectors, the number of *, the number of + in the expression, etc.

@giordano
Copy link
Author

Thank you.

As I said in the first message, it does depend on the number of operations, it works with

@. d_lng * d + M_lng * M

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

2 participants