Re: [julia-users] Tracking down type instability

2016-09-16 Thread Yichao Yu
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

2016-09-16 Thread Ben Ward
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

2016-09-15 Thread Kristoffer Carlsson
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

2016-09-15 Thread Yichao Yu
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

2016-09-15 Thread Ben Ward
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