Unusual @code_warntype behavior in 0.6?

question

#1
eigenvector_centrality(g::AbstractGraph) = norm.(eigs(adjacency_matrix(g), nev=1)[2])

julia> @code_warntype(eigenvector_centrality(g))
Variables:
  #self#::LightGraphs.#eigenvector_centrality
  g::LightGraphs.SimpleGraphs.SimpleGraph{Int64}

Body:
  begin
      SSAValue(0) = $(Expr(:invoke, MethodInstance for (::Base.LinAlg.#kw##eigs)(::Array{Any,1}, ::Base.LinAlg.#eigs, ::SparseMatrixCSC{Int64,Int64}), :($(QuoteNode(Base.LinAlg.#eigs))), :($(Expr(:invoke, MethodInstance for vector_any(::Any, ::Vararg{Any,N} where N), :(Base.vector_any), :(:nev), 1))), :(LightGraphs.eigs), :($(Expr(:invoke, MethodInstance for adjacency_matrix(::LightGraphs.SimpleGraphs.SimpleGraph{Int64}, ::Symbol, ::DataType), :(LightGraphs.adjacency_matrix), :(g), :(:out), :(LightGraphs.Int))))))
      return (Base.broadcast)(LightGraphs.norm, (Base.getfield)(SSAValue(0), 2)::Any)::Any
  end::Any

and

julia> @code_warntype(adjacency_matrix(g))
Variables:
  #self#::LightGraphs.#adjacency_matrix
  g::LightGraphs.SimpleGraphs.SimpleGraph{Int64}

Body:
  begin
      return $(Expr(:invoke, MethodInstance for adjacency_matrix(::LightGraphs.SimpleGraphs.SimpleGraph{Int64}, ::Symbol, ::DataType), :(#self#), :(g), :(:out), :(LightGraphs.Int)))
  end::SparseMatrixCSC{Int64,Int64}

Why is the former inferring an Any type?


#2

eigs is type unstable, because it might return a real or a complex matrix, and the compiler doesn’t have enough information to figure out that norm.(...) will always be a Float64 matrix. You can fix this by adding a type assertion:

eigenvector_centrality(g::AbstractGraph) = norm.(eigs(adjacency_matrix(g), nev=1)[2])::Matrix{Float64}

#3

@fengyang.wang - thank you. I asserted Vector{Float64} and that seemed to do the trick:

eigenvector_centrality(g::AbstractGraph) =
    vec(norm.(eigs(adjacency_matrix(g), nev=1)[2]))::Vector{Float64}

julia> @code_warntype(eigenvector_centrality(g))
Variables:
  #self#::LightGraphs.#eigenvector_centrality
  g::LightGraphs.SimpleGraphs.SimpleGraph{Int64}

Body:
  begin
      SSAValue(0) = $(Expr(:invoke, MethodInstance for (::Base.LinAlg.#kw##eigs)(::Array{Any,1}, ::Base.LinAlg.#eigs, ::SparseMatrixCSC{Int64,Int64}), :($(QuoteNode(Base.LinAlg.#eigs))), :($(Expr(:invoke, MethodInstance for vector_any(::Any, ::Vararg{Any,N} where N), :(Base.vector_any), :(:nev), 1))), :(LightGraphs.eigs), :($(Expr(:invoke, MethodInstance for adjacency_matrix(::LightGraphs.SimpleGraphs.SimpleGraph{Int64}, ::Symbol, ::DataType), :(LightGraphs.adjacency_matrix), :(g), :(:out), :(LightGraphs.Int))))))
      return (Core.typeassert)((LightGraphs.vec)((Base.broadcast)(LightGraphs.norm, (Base.getfield)(SSAValue(0), 2)::Any)::Any)::Any, Array{Float64,1})::Array{Float64,1}
  end::Array{Float64,1}