Re: [julia-users] Tracking down type instability
On Sep 16, 2016 11:30 AM, "Ben Ward" wrote: > > I see, but I thought I'd like to try and remove the instability as I wonder if it's one of the things preventing vectorisation of the @inbounds loop in the `distance` function. Log can't be vectorized. Not yet at least. > > > On Friday, September 16, 2016 at 7:54:33 AM UTC+1, Kristoffer Carlsson wrote: >> >> It looks fine because for both the SSAValues with "problems" you later have: >> >> p::Array{Float64,1} = SSAValue(15) >> >> l::Array{Int64,1} = SSAValue(17) >> >> >> so they actually get correctly inferred. >> >> As long as your variables list and return value is ok then things are most likely ok. >> >> On Friday, September 16, 2016 at 4:37:09 AM UTC+2, Yichao Yu wrote: >>> >>> On Thu, Sep 15, 2016 at 10:08 AM, Ben Ward wrote: >>> > Hi I have two functions and a function which calls them: >>> > >>> > @inline function expected_distance(::Type{JukesCantor69}, p::Float64) >>> > return -0.75 * log(1 - 4 * p / 3) >>> > end >>> > >>> > @inline function variance(::Type{JukesCantor69}, p::Float64, l::Int64) >>> > return p * (1 - p) / (((1 - 4 * p / 3) ^ 2) * l) >>> > end >>> > >>> > function distance{A<:NucleotideAlphabet}(::Type{JukesCantor69}, >>> > seqs::Vector{BioSequence{A}}) >>> > p, l = distance(Proportion{AnyMutation}, seqs) >>> > D = Vector{Float64}(length(p)) >>> > V = Vector{Float64}(length(p)) >>> > @inbounds for i in 1:length(p) >>> > D[i] = expected_distance(JukesCantor69, p[i]) >>> > V[i] = variance(JukesCantor69, p[i], l[i]) >>> > end >>> > return D, V >>> > end >>> > >>> > But I'm seeing type uncertainty: >>> > >>> > @code_warntype distance(JukesCantor69, dnas) >>> > >>> > Variables: >>> > >>> > #self#::Bio.Var.#distance >>> > >>> > #unused#::Type{Bio.Var.JukesCantor69} >>> > >>> > seqs::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1} >>> > >>> > p::Array{Float64,1} >>> > >>> > l::Array{Int64,1} >>> > >>> > #temp#@_6::Int64 >>> > >>> > D::Array{Float64,1} >>> > >>> > V::Array{Float64,1} >>> > >>> > #temp#@_9::Int64 >>> > >>> > i::Int64 >>> > >>> > >>> > Body: >>> > >>> > begin >>> > >>> > SSAValue(0) = $(Expr(:invoke, LambdaInfo for >>> > distance(::Type{Bio.Var.Proportion{Bio.Var.AnyMutation}}, >>> > ::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1}), >>> > :(Bio.Var.distance), Bio.Var.Proportion{Bio.Var.AnyMutation}, :(seqs))) >>> > >>> > #temp#@_6::Int64 = $(QuoteNode(1)) >>> > >>> > SSAValue(15) = >>> > (Base.getfield)(SSAValue(0),1)::Union{Array{Float64,1},Array{Int64,1}} >>> >>> I guess we should probably print ssavalue types to make this easier to analyse >>> >>> There's likely no type instability and the warning here is just spurious >>> >>> > >>> > SSAValue(16) = (Base.box)(Int64,(Base.add_int)(1,1)) >>> > >>> > p::Array{Float64,1} = SSAValue(15) >>> > >>> > #temp#@_6::Int64 = SSAValue(16) >>> > >>> > SSAValue(17) = >>> > (Base.getfield)(SSAValue(0),2)::Union{Array{Float64,1},Array{Int64,1}} >>> > >>> > SSAValue(18) = (Base.box)(Int64,(Base.add_int)(2,1)) >>> > >>> > l::Array{Int64,1} = SSAValue(17) >>> > >>> > #temp#@_6::Int64 = SSAValue(18) # line 314: >>> > >>> > SSAValue(7) = (Base.arraylen)(p::Array{Float64,1})::Int64 >>> > >>> > D::Array{Float64,1} = >>> > (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(7),0)::Array{Float64,1} >>> > # line 315: >>> > >>> > SSAValue(9) = (Base.arraylen)(p::Array{Float64,1})::Int64 >>> > >>> > V::Array{Float64,1} = >>> > (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(9),0)::Array{Float64,1} >>> > # line 316: >>> > >>> > $(Expr(:inbounds, true)) >>> > >>> > SSAValue(11) = (Base.arraylen)(p::Array{Float64,1})::Int64 >>> > >>> > SSAValue(19) = >>> > (Base.select_value)((Base.sle_int)(1,SSAValue(11))::Bool,SSAValue(11),(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64 >>> > >>> > #temp#@_9::Int64 = 1 >>> > >>> > 22: >>> > >>> > unless (Base.box)(Base.Bool,(Base.not_int)((#temp#@_9::Int64 === >>> > (Base.box)(Int64,(Base.add_int)(SSAValue(19),1)))::Bool)) goto 43 >>> > >>> > SSAValue(20) = #temp#@_9::Int64 >>> > >>> > SSAValue(21) = (Base.box)(Int64,(Base.add_int)(#temp#@_9::Int64,1)) >>> > >>> > i::Int64 = SSAValue(20) >>> > >>> > #temp#@_9::Int64 = SSAValue(21) # line 317: >>> > >>> > SSAValue(12) = (Base.arrayref)(p::Array{Float64,1},i::Int64)::Float64 >>> > >>> > $(Expr(:inbounds, false)) >>> > >>> > # meta: location /Users/bward/.julia/v0.5/Bio/src/var/distances.jl >>> > expected_distance 69 >>> > >>> > SSAValue(13) = $(Expr(:invoke, LambdaInfo for log(::Float64), >>> > :(Bio.Var.log), >>> > :((Base.box)(Base.Floa
Re: [julia-users] Tracking down type instability
I see, but I thought I'd like to try and remove the instability as I wonder if it's one of the things preventing vectorisation of the @inbounds loop in the `distance` function. On Friday, September 16, 2016 at 7:54:33 AM UTC+1, Kristoffer Carlsson wrote: > > It looks fine because for both the SSAValues with "problems" you later > have: > > p::Array{Float64,1} = SSAValue(15) > > l::Array{Int64,1} = SSAValue(17) > > so they actually get correctly inferred. > > As long as your variables list and return value is ok then things are most > likely ok. > > On Friday, September 16, 2016 at 4:37:09 AM UTC+2, Yichao Yu wrote: >> >> On Thu, Sep 15, 2016 at 10:08 AM, Ben Ward wrote: >> > Hi I have two functions and a function which calls them: >> > >> > @inline function expected_distance(::Type{JukesCantor69}, p::Float64) >> > return -0.75 * log(1 - 4 * p / 3) >> > end >> > >> > @inline function variance(::Type{JukesCantor69}, p::Float64, l::Int64) >> > return p * (1 - p) / (((1 - 4 * p / 3) ^ 2) * l) >> > end >> > >> > function distance{A<:NucleotideAlphabet}(::Type{JukesCantor69}, >> > seqs::Vector{BioSequence{A}}) >> > p, l = distance(Proportion{AnyMutation}, seqs) >> > D = Vector{Float64}(length(p)) >> > V = Vector{Float64}(length(p)) >> > @inbounds for i in 1:length(p) >> > D[i] = expected_distance(JukesCantor69, p[i]) >> > V[i] = variance(JukesCantor69, p[i], l[i]) >> > end >> > return D, V >> > end >> > >> > But I'm seeing type uncertainty: >> > >> > @code_warntype distance(JukesCantor69, dnas) >> > >> > Variables: >> > >> > #self#::Bio.Var.#distance >> > >> > #unused#::Type{Bio.Var.JukesCantor69} >> > >> > seqs::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1} >> > >> > p::Array{Float64,1} >> > >> > l::Array{Int64,1} >> > >> > #temp#@_6::Int64 >> > >> > D::Array{Float64,1} >> > >> > V::Array{Float64,1} >> > >> > #temp#@_9::Int64 >> > >> > i::Int64 >> > >> > >> > Body: >> > >> > begin >> > >> > SSAValue(0) = $(Expr(:invoke, LambdaInfo for >> > distance(::Type{Bio.Var.Proportion{Bio.Var.AnyMutation}}, >> > ::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1}), >> > :(Bio.Var.distance), Bio.Var.Proportion{Bio.Var.AnyMutation}, :(seqs))) >> > >> > #temp#@_6::Int64 = $(QuoteNode(1)) >> > >> > SSAValue(15) = >> > (Base.getfield)(SSAValue(0),1)::Union{Array{Float64,1},Array{Int64,1}} >> >> I guess we should probably print ssavalue types to make this easier to >> analyse >> >> There's likely no type instability and the warning here is just spurious >> >> > >> > SSAValue(16) = (Base.box)(Int64,(Base.add_int)(1,1)) >> > >> > p::Array{Float64,1} = SSAValue(15) >> > >> > #temp#@_6::Int64 = SSAValue(16) >> > >> > SSAValue(17) = >> > (Base.getfield)(SSAValue(0),2)::Union{Array{Float64,1},Array{Int64,1}} >> > >> > SSAValue(18) = (Base.box)(Int64,(Base.add_int)(2,1)) >> > >> > l::Array{Int64,1} = SSAValue(17) >> > >> > #temp#@_6::Int64 = SSAValue(18) # line 314: >> > >> > SSAValue(7) = (Base.arraylen)(p::Array{Float64,1})::Int64 >> > >> > D::Array{Float64,1} = >> > >> (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(7),0)::Array{Float64,1} >> >> >> > # line 315: >> > >> > SSAValue(9) = (Base.arraylen)(p::Array{Float64,1})::Int64 >> > >> > V::Array{Float64,1} = >> > >> (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(9),0)::Array{Float64,1} >> >> >> > # line 316: >> > >> > $(Expr(:inbounds, true)) >> > >> > SSAValue(11) = (Base.arraylen)(p::Array{Float64,1})::Int64 >> > >> > SSAValue(19) = >> > >> (Base.select_value)((Base.sle_int)(1,SSAValue(11))::Bool,SSAValue(11),(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64 >> >> >> > >> > #temp#@_9::Int64 = 1 >> > >> > 22: >> > >> > unless (Base.box)(Base.Bool,(Base.not_int)((#temp#@_9::Int64 === >> > (Base.box)(Int64,(Base.add_int)(SSAValue(19),1)))::Bool)) goto 43 >> > >> > SSAValue(20) = #temp#@_9::Int64 >> > >> > SSAValue(21) = >> (Base.box)(Int64,(Base.add_int)(#temp#@_9::Int64,1)) >> > >> > i::Int64 = SSAValue(20) >> > >> > #temp#@_9::Int64 = SSAValue(21) # line 317: >> > >> > SSAValue(12) = >> (Base.arrayref)(p::Array{Float64,1},i::Int64)::Float64 >> > >> > $(Expr(:inbounds, false)) >> > >> > # meta: location >> /Users/bward/.julia/v0.5/Bio/src/var/distances.jl >> > expected_distance 69 >> > >> > SSAValue(13) = $(Expr(:invoke, LambdaInfo for log(::Float64), >> > :(Bio.Var.log), >> > >> :((Base.box)(Base.Float64,(Base.sub_float)((Base.box)(Float64,(Base.sitofp)(Float6
Re: [julia-users] Tracking down type instability
It looks fine because for both the SSAValues with "problems" you later have: p::Array{Float64,1} = SSAValue(15) l::Array{Int64,1} = SSAValue(17) so they actually get correctly inferred. As long as your variables list and return value is ok then things are most likely ok. On Friday, September 16, 2016 at 4:37:09 AM UTC+2, Yichao Yu wrote: > > On Thu, Sep 15, 2016 at 10:08 AM, Ben Ward > wrote: > > Hi I have two functions and a function which calls them: > > > > @inline function expected_distance(::Type{JukesCantor69}, p::Float64) > > return -0.75 * log(1 - 4 * p / 3) > > end > > > > @inline function variance(::Type{JukesCantor69}, p::Float64, l::Int64) > > return p * (1 - p) / (((1 - 4 * p / 3) ^ 2) * l) > > end > > > > function distance{A<:NucleotideAlphabet}(::Type{JukesCantor69}, > > seqs::Vector{BioSequence{A}}) > > p, l = distance(Proportion{AnyMutation}, seqs) > > D = Vector{Float64}(length(p)) > > V = Vector{Float64}(length(p)) > > @inbounds for i in 1:length(p) > > D[i] = expected_distance(JukesCantor69, p[i]) > > V[i] = variance(JukesCantor69, p[i], l[i]) > > end > > return D, V > > end > > > > But I'm seeing type uncertainty: > > > > @code_warntype distance(JukesCantor69, dnas) > > > > Variables: > > > > #self#::Bio.Var.#distance > > > > #unused#::Type{Bio.Var.JukesCantor69} > > > > seqs::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1} > > > > p::Array{Float64,1} > > > > l::Array{Int64,1} > > > > #temp#@_6::Int64 > > > > D::Array{Float64,1} > > > > V::Array{Float64,1} > > > > #temp#@_9::Int64 > > > > i::Int64 > > > > > > Body: > > > > begin > > > > SSAValue(0) = $(Expr(:invoke, LambdaInfo for > > distance(::Type{Bio.Var.Proportion{Bio.Var.AnyMutation}}, > > ::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1}), > > :(Bio.Var.distance), Bio.Var.Proportion{Bio.Var.AnyMutation}, :(seqs))) > > > > #temp#@_6::Int64 = $(QuoteNode(1)) > > > > SSAValue(15) = > > (Base.getfield)(SSAValue(0),1)::Union{Array{Float64,1},Array{Int64,1}} > > I guess we should probably print ssavalue types to make this easier to > analyse > > There's likely no type instability and the warning here is just spurious > > > > > SSAValue(16) = (Base.box)(Int64,(Base.add_int)(1,1)) > > > > p::Array{Float64,1} = SSAValue(15) > > > > #temp#@_6::Int64 = SSAValue(16) > > > > SSAValue(17) = > > (Base.getfield)(SSAValue(0),2)::Union{Array{Float64,1},Array{Int64,1}} > > > > SSAValue(18) = (Base.box)(Int64,(Base.add_int)(2,1)) > > > > l::Array{Int64,1} = SSAValue(17) > > > > #temp#@_6::Int64 = SSAValue(18) # line 314: > > > > SSAValue(7) = (Base.arraylen)(p::Array{Float64,1})::Int64 > > > > D::Array{Float64,1} = > > > (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(7),0)::Array{Float64,1} > > > > # line 315: > > > > SSAValue(9) = (Base.arraylen)(p::Array{Float64,1})::Int64 > > > > V::Array{Float64,1} = > > > (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(9),0)::Array{Float64,1} > > > > # line 316: > > > > $(Expr(:inbounds, true)) > > > > SSAValue(11) = (Base.arraylen)(p::Array{Float64,1})::Int64 > > > > SSAValue(19) = > > > (Base.select_value)((Base.sle_int)(1,SSAValue(11))::Bool,SSAValue(11),(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64 > > > > > > #temp#@_9::Int64 = 1 > > > > 22: > > > > unless (Base.box)(Base.Bool,(Base.not_int)((#temp#@_9::Int64 === > > (Base.box)(Int64,(Base.add_int)(SSAValue(19),1)))::Bool)) goto 43 > > > > SSAValue(20) = #temp#@_9::Int64 > > > > SSAValue(21) = > (Base.box)(Int64,(Base.add_int)(#temp#@_9::Int64,1)) > > > > i::Int64 = SSAValue(20) > > > > #temp#@_9::Int64 = SSAValue(21) # line 317: > > > > SSAValue(12) = > (Base.arrayref)(p::Array{Float64,1},i::Int64)::Float64 > > > > $(Expr(:inbounds, false)) > > > > # meta: location /Users/bward/.julia/v0.5/Bio/src/var/distances.jl > > expected_distance 69 > > > > SSAValue(13) = $(Expr(:invoke, LambdaInfo for log(::Float64), > > :(Bio.Var.log), > > > :((Base.box)(Base.Float64,(Base.sub_float)((Base.box)(Float64,(Base.sitofp)(Float64,1)),(Base.box)(Base.Float64,(Base.div_float)((Base.box)(Base.Float64,(Base.mul_float)((Base.box)(Float64,(Base.sitofp)(Float64,4)),SSAValue(12))),(Base.box)(Float64,(Base.sitofp)(Float64,3) > > > > > > # meta: pop location > > > > $(Expr(:inbounds, :pop)) > > > > SSAValue(5) = > > (Base.box)(Base.Float64,(Base.mul_float)(-0.75,SSAValue(13))) > > > > > > > (Base.arrayset)(D::Array{Floa
Re: [julia-users] Tracking down type instability
On Thu, Sep 15, 2016 at 10:08 AM, Ben Ward wrote: > Hi I have two functions and a function which calls them: > > @inline function expected_distance(::Type{JukesCantor69}, p::Float64) > return -0.75 * log(1 - 4 * p / 3) > end > > @inline function variance(::Type{JukesCantor69}, p::Float64, l::Int64) > return p * (1 - p) / (((1 - 4 * p / 3) ^ 2) * l) > end > > function distance{A<:NucleotideAlphabet}(::Type{JukesCantor69}, > seqs::Vector{BioSequence{A}}) > p, l = distance(Proportion{AnyMutation}, seqs) > D = Vector{Float64}(length(p)) > V = Vector{Float64}(length(p)) > @inbounds for i in 1:length(p) > D[i] = expected_distance(JukesCantor69, p[i]) > V[i] = variance(JukesCantor69, p[i], l[i]) > end > return D, V > end > > But I'm seeing type uncertainty: > > @code_warntype distance(JukesCantor69, dnas) > > Variables: > > #self#::Bio.Var.#distance > > #unused#::Type{Bio.Var.JukesCantor69} > > seqs::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1} > > p::Array{Float64,1} > > l::Array{Int64,1} > > #temp#@_6::Int64 > > D::Array{Float64,1} > > V::Array{Float64,1} > > #temp#@_9::Int64 > > i::Int64 > > > Body: > > begin > > SSAValue(0) = $(Expr(:invoke, LambdaInfo for > distance(::Type{Bio.Var.Proportion{Bio.Var.AnyMutation}}, > ::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1}), > :(Bio.Var.distance), Bio.Var.Proportion{Bio.Var.AnyMutation}, :(seqs))) > > #temp#@_6::Int64 = $(QuoteNode(1)) > > SSAValue(15) = > (Base.getfield)(SSAValue(0),1)::Union{Array{Float64,1},Array{Int64,1}} I guess we should probably print ssavalue types to make this easier to analyse There's likely no type instability and the warning here is just spurious > > SSAValue(16) = (Base.box)(Int64,(Base.add_int)(1,1)) > > p::Array{Float64,1} = SSAValue(15) > > #temp#@_6::Int64 = SSAValue(16) > > SSAValue(17) = > (Base.getfield)(SSAValue(0),2)::Union{Array{Float64,1},Array{Int64,1}} > > SSAValue(18) = (Base.box)(Int64,(Base.add_int)(2,1)) > > l::Array{Int64,1} = SSAValue(17) > > #temp#@_6::Int64 = SSAValue(18) # line 314: > > SSAValue(7) = (Base.arraylen)(p::Array{Float64,1})::Int64 > > D::Array{Float64,1} = > (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(7),0)::Array{Float64,1} > # line 315: > > SSAValue(9) = (Base.arraylen)(p::Array{Float64,1})::Int64 > > V::Array{Float64,1} = > (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(9),0)::Array{Float64,1} > # line 316: > > $(Expr(:inbounds, true)) > > SSAValue(11) = (Base.arraylen)(p::Array{Float64,1})::Int64 > > SSAValue(19) = > (Base.select_value)((Base.sle_int)(1,SSAValue(11))::Bool,SSAValue(11),(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64 > > #temp#@_9::Int64 = 1 > > 22: > > unless (Base.box)(Base.Bool,(Base.not_int)((#temp#@_9::Int64 === > (Base.box)(Int64,(Base.add_int)(SSAValue(19),1)))::Bool)) goto 43 > > SSAValue(20) = #temp#@_9::Int64 > > SSAValue(21) = (Base.box)(Int64,(Base.add_int)(#temp#@_9::Int64,1)) > > i::Int64 = SSAValue(20) > > #temp#@_9::Int64 = SSAValue(21) # line 317: > > SSAValue(12) = (Base.arrayref)(p::Array{Float64,1},i::Int64)::Float64 > > $(Expr(:inbounds, false)) > > # meta: location /Users/bward/.julia/v0.5/Bio/src/var/distances.jl > expected_distance 69 > > SSAValue(13) = $(Expr(:invoke, LambdaInfo for log(::Float64), > :(Bio.Var.log), > :((Base.box)(Base.Float64,(Base.sub_float)((Base.box)(Float64,(Base.sitofp)(Float64,1)),(Base.box)(Base.Float64,(Base.div_float)((Base.box)(Base.Float64,(Base.mul_float)((Base.box)(Float64,(Base.sitofp)(Float64,4)),SSAValue(12))),(Base.box)(Float64,(Base.sitofp)(Float64,3) > > # meta: pop location > > $(Expr(:inbounds, :pop)) > > SSAValue(5) = > (Base.box)(Base.Float64,(Base.mul_float)(-0.75,SSAValue(13))) > > > (Base.arrayset)(D::Array{Float64,1},SSAValue(5),i::Int64)::Array{Float64,1} > # line 318: > > SSAValue(14) = (Base.arrayref)(p::Array{Float64,1},i::Int64)::Float64 > > SSAValue(6) = > (Base.box)(Base.Float64,(Base.div_float)((Base.box)(Base.Float64,(Base.mul_float)(SSAValue(14),(Base.box)(Base.Float64,(Base.sub_float)((Base.box)(Float64,(Base.sitofp)(Float64,1)),SSAValue(14),(Base.box)(Base.Float64,(Base.mul_float)((Base.Math.box)(Base.Math.Float64,(Base.Math.powi_llvm)((Base.box)(Base.Float64,(Base.sub_float)((Base.box)(Float64,(Base.sitofp)(Float64,1)),(Base.box)(Base.Float64,(Base.div_float)((Base.box)(Base.Float64,(Base.mul_float)((Base.box)(Float64,(Base.sitofp)(Float64,4)),SSAValue(14))),(Base.box)(Float64,(Base.sitofp)(Float64,3)),(Base.box)(Int32,(Base.checked_trunc_sint)(Int32,2::Float64,
[julia-users] Tracking down type instability
Hi I have two functions and a function which calls them: @inline function expected_distance(::Type{JukesCantor69}, p::Float64) return -0.75 * log(1 - 4 * p / 3) end @inline function variance(::Type{JukesCantor69}, p::Float64, l::Int64) return p * (1 - p) / (((1 - 4 * p / 3) ^ 2) * l) end function distance{A<:NucleotideAlphabet}(::Type{JukesCantor69}, seqs::Vector{BioSequence{A}}) p, l = distance(Proportion{AnyMutation}, seqs) D = Vector{Float64}(length(p)) V = Vector{Float64}(length(p)) @inbounds for i in 1:length(p) D[i] = expected_distance(JukesCantor69, p[i]) V[i] = variance(JukesCantor69, p[i], l[i]) end return D, V end But I'm seeing type uncertainty: *@code_warntype distance(JukesCantor69, dnas)* Variables: #self#::Bio.Var.#distance #unused#::Type{Bio.Var.JukesCantor69} seqs::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1} p::Array{Float64,1} l::Array{Int64,1} #temp#@_6::Int64 D::Array{Float64,1} V::Array{Float64,1} #temp#@_9::Int64 i::Int64 Body: begin SSAValue(0) = $(Expr(:invoke, LambdaInfo for distance(::Type{Bio.Var.Proportion{Bio.Var.AnyMutation}}, ::Array{Bio.Seq.BioSequence{Bio.Seq.DNAAlphabet{4}},1}), :(Bio.Var.distance), Bio.Var.Proportion{Bio.Var.AnyMutation}, :(seqs))) #temp#@_6::Int64 = $(QuoteNode(1)) SSAValue(15) = (Base.getfield)(SSAValue(0),1) *::Union{Array{Float64,1},Array{Int64,1}}* SSAValue(16) = (Base.box)(Int64,(Base.add_int)(1,1)) p::Array{Float64,1} = SSAValue(15) #temp#@_6::Int64 = SSAValue(16) SSAValue(17) = (Base.getfield)(SSAValue(0),2) *::Union{Array{Float64,1},Array{Int64,1}}* SSAValue(18) = (Base.box)(Int64,(Base.add_int)(2,1)) l::Array{Int64,1} = SSAValue(17) #temp#@_6::Int64 = SSAValue(18) # line 314: SSAValue(7) = (Base.arraylen)(p::Array{Float64,1})::Int64 D::Array{Float64,1} = (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(7),0)::Array{Float64,1} # line 315: SSAValue(9) = (Base.arraylen)(p::Array{Float64,1})::Int64 V::Array{Float64,1} = (Core.ccall)(:jl_alloc_array_1d,(Core.apply_type)(Core.Array,Float64,1)::Type{Array{Float64,1}},(Core.svec)(Core.Any,Core.Int)::SimpleVector,Array{Float64,1},0,SSAValue(9),0)::Array{Float64,1} # line 316: $(Expr(:inbounds, true)) SSAValue(11) = (Base.arraylen)(p::Array{Float64,1})::Int64 SSAValue(19) = (Base.select_value)((Base.sle_int)(1,SSAValue(11))::Bool,SSAValue(11),(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64 #temp#@_9::Int64 = 1 22: unless (Base.box)(Base.Bool,(Base.not_int)((#temp#@_9::Int64 === (Base.box)(Int64,(Base.add_int)(SSAValue(19),1)))::Bool)) goto 43 SSAValue(20) = #temp#@_9::Int64 SSAValue(21) = (Base.box)(Int64,(Base.add_int)(#temp#@_9::Int64,1)) i::Int64 = SSAValue(20) #temp#@_9::Int64 = SSAValue(21) # line 317: SSAValue(12) = (Base.arrayref)(p::Array{Float64,1},i::Int64)::Float64 $(Expr(:inbounds, false)) # meta: location /Users/bward/.julia/v0.5/Bio/src/var/distances.jl expected_distance 69 SSAValue(13) = $(Expr(:invoke, LambdaInfo for log(::Float64), :(Bio.Var.log), :((Base.box)(Base.Float64,(Base.sub_float)((Base.box)(Float64,(Base.sitofp)(Float64,1)),(Base.box)(Base.Float64,(Base.div_float)((Base.box)(Base.Float64,(Base.mul_float)((Base.box)(Float64,(Base.sitofp)(Float64,4)),SSAValue(12))),(Base.box)(Float64,(Base.sitofp)(Float64,3) # meta: pop location $(Expr(:inbounds, :pop)) SSAValue(5) = (Base.box)(Base.Float64,(Base.mul_float)(-0.75,SSAValue(13))) (Base.arrayset)(D::Array{Float64,1},SSAValue(5),i::Int64)::Array{Float64,1} # line 318: SSAValue(14) = (Base.arrayref)(p::Array{Float64,1},i::Int64)::Float64 SSAValue(6) = (Base.box)(Base.Float64,(Base.div_float)((Base.box)(Base.Float64,(Base.mul_float)(SSAValue(14),(Base.box)(Base.Float64,(Base.sub_float)((Base.box)(Float64,(Base.sitofp)(Float64,1)),SSAValue(14),(Base.box)(Base.Float64,(Base.mul_float)((Base.Math.box)(Base.Math.Float64,(Base.Math.powi_llvm)((Base.box)(Base.Float64,(Base.sub_float)((Base.box)(Float64,(Base.sitofp)(Float64,1)),(Base.box)(Base.Float64,(Base.div_float)((Base.box)(Base.Float64,(Base.mul_float)((Base.box)(Float64,(Base.sitofp)(Float64,4)),SSAValue(14))),(Base.box)(Float64,(Base.sitofp)(Float64,3)),(Base.box)(Int32,(Base.checked_trunc_sint)(Int32,2::Float64,(Base.box)(Float64,(Base.sitofp)(Float64,(Base.arrayref)(l::Array{Int64,1},i::Int64)::Int64)) (Base.arrayset)(V::Array{Float64,1},SSAValue(6),i::Int64)::Array{Float64,1} 41: goto 22 43: $(Expr(:inbounds, :pop)) # line 320: return (Core.tuple)(D::Array{Float64,1},V::Array{Float64,1})::Tuple{Array{Float64,1},Array{Float64,1}} end::Tuple{Arra