julia> function cwt(a, b)
for i β linspace(a, b, 4)
println(i, " ", typeof(i))
end
end
cwt (generic function with 1 method)
julia> cwt(0f0, 3f0)
0.0 Float32
1.0 Float32
2.0 Float32
3.0 Float32
julia> @code_warntype cwt(0f0, 3f0)
Variables:
#self# <optimized out>
a::Float32
b::Float32
i::Any
#temp#@_5::Any
#temp#@_6::Core.MethodInstance
#temp#@_7::Union{Int64, Tuple{Any,Int64}}
#temp#@_8 <optimized out>
#temp#@_9 <optimized out>
Body:
begin
SSAValue(0) = $(Expr(:invoke, MethodInstance for linspace(::Float32, ::Float32, ::Int64), :(Main.linspace), :(a), :(b), 4))
unless (SSAValue(0) isa StepRangeLen{Float32,Base.TwicePrecision{Float32},Base.TwicePrecision{Float32}})::Bool goto 5
#temp#@_6::Core.MethodInstance = MethodInstance for start(::StepRangeLen{Float32,Base.TwicePrecision{Float32},Base.TwicePrecision{Float32}})
goto 10
5:
goto 7
7:
#temp#@_7::Union{Int64, Tuple{Any,Int64}} = (Base.start)(SSAValue(0))::Union{Int64, Tuple{Any,Int64}}
goto 12
10:
#temp#@_7::Union{Int64, Tuple{Any,Int64}} = $(Expr(:invoke, :(#temp#@_6), :(Base.start), SSAValue(0)))
12:
#temp#@_5::Any = #temp#@_7::Union{Int64, Tuple{Any,Int64}}
14:
unless !((Base.done)(SSAValue(0), #temp#@_5::Any)::Any)::Any goto 23
SSAValue(1) = (Base.next)(SSAValue(0), #temp#@_5::Any)::Tuple{Any,Any}
i::Any = (Core.getfield)(SSAValue(1), 1)::Any
#temp#@_5::Any = (Core.getfield)(SSAValue(1), 2)::Any # line 3:
(Main.println)(i::Any, " ", (Main.typeof)(i::Any)::DataType)::Void
21:
goto 14
23:
return
end::Void
julia> @code_warntype cwt(0, 3)
Variables:
#self# <optimized out>
a::Int64
b::Int64
i::Float64
#temp#@_5::Int64
u@_6::Int64
shift_hi <optimized out>
shift_lo <optimized out>
x_hi <optimized out>
x_lo <optimized out>
#temp#@_11 <optimized out>
#temp#@_12 <optimized out>
w::Float64
u@_14::Float64
v::Float64
Body:
begin
SSAValue(0) = $(Expr(:invoke, MethodInstance for linspace(::Type{Float64}, ::Int64, ::Int64, ::Int64, ::Int64), :(Base.linspace), :(Base.Float64), :(a), :(b), 4, 1))
#temp#@_5::Int64 = 1
3:
unless (Base.not_int)((Base.slt_int)((Core.getfield)(SSAValue(0), :len)::Int64, #temp#@_5::Int64)::Bool)::Bool goto 46
$(Expr(:inbounds, false))
# meta: location twiceprecision.jl next 187
# meta: location twiceprecision.jl unsafe_getindex 194
u@_6::Int64 = (Base.sub_int)(#temp#@_5::Int64, (Core.getfield)(SSAValue(0), :offset)::Int64)::Int64 # line 195:
SSAValue(2) = (Base.mul_float)((Base.sitofp)(Float64, u@_6::Int64)::Float64, (Core.getfield)((Core.getfield)(SSAValue(0), :step)::Base.TwicePrecision{Float64}, :hi)::Float64)::Float64
SSAValue(3) = (Base.mul_float)((Base.sitofp)(Float64, u@_6::Int64)::Float64, (Core.getfield)((Core.getfield)(SSAValue(0), :step)::Base.TwicePrecision{Float64}, :lo)::Float64)::Float64 # line 196:
# meta: location twiceprecision.jl add2 445
u@_14::Float64 = (Core.getfield)((Core.getfield)(SSAValue(0), :ref)::Base.TwicePrecision{Float64}, :hi)::Float64
v::Float64 = SSAValue(2)
SSAValue(7) = (Base.select_value)((Base.lt_float)((Base.abs_float)(u@_14::Float64)::Float64, (Base.abs_float)(v::Float64)::Float64)::Bool, (Core.tuple)(v::Float64, u@_14::Float64)::Tuple{Float64,Float64}, (Core.tuple)(u@_14::Float64, v::Float64)::Tuple{Float64,Float64})::Tuple{Float64,Float64}
SSAValue(10) = (Base.getfield)(SSAValue(7), 1)::Float64
u@_14::Float64 = SSAValue(10)
SSAValue(12) = (Base.getfield)(SSAValue(7), 2)::Float64
v::Float64 = SSAValue(12) # line 446:
w::Float64 = (Base.add_float)(u@_14::Float64, v::Float64)::Float64
# meta: pop location
SSAValue(15) = (Base.add_float)((Base.sub_float)(u@_14::Float64, w::Float64)::Float64, v::Float64)::Float64
# meta: pop location
# meta: pop location
$(Expr(:inbounds, :pop))
SSAValue(24) = (Base.add_float)(w::Float64, (Base.add_float)(SSAValue(15), (Base.add_float)(SSAValue(3), (Core.getfield)((Core.getfield)(SSAValue(0), :ref)::Base.TwicePrecision{Float64}, :lo)::Float64)::Float64)::Float64)::Float64
SSAValue(25) = (Base.add_int)(#temp#@_5::Int64, 1)::Int64
i::Float64 = SSAValue(24)
#temp#@_5::Int64 = SSAValue(25) # line 3:
SSAValue(26) = i::Float64
SSAValue(27) = Float64
$(Expr(:inbounds, false))
# meta: location coreio.jl println 5
SSAValue(19) = (Core.typeassert)(Base.STDOUT, Base.IO)::IO
SSAValue(21) = SSAValue(26)
SSAValue(22) = " "
SSAValue(23) = SSAValue(27)
# meta: pop location
$(Expr(:inbounds, :pop))
(Base.print)(SSAValue(19), SSAValue(21), SSAValue(22), SSAValue(23), $(QuoteNode('\n')))::Void
44:
goto 3
46:
return
end::Void
julia> @code_warntype cwt(0.0, 3.0)
Variables:
#self# <optimized out>
a::Float64
b::Float64
i::Float64
#temp#@_5::Int64
u@_6::Int64
shift_hi <optimized out>
shift_lo <optimized out>
x_hi <optimized out>
x_lo <optimized out>
#temp#@_11 <optimized out>
#temp#@_12 <optimized out>
w::Float64
u@_14::Float64
v::Float64
Body:
begin
SSAValue(0) = $(Expr(:invoke, MethodInstance for linspace(::Float64, ::Float64, ::Int64), :(Main.linspace), :(a), :(b), 4))
#temp#@_5::Int64 = 1
3:
unless (Base.not_int)((Base.slt_int)((Core.getfield)(SSAValue(0), :len)::Int64, #temp#@_5::Int64)::Bool)::Bool goto 46
$(Expr(:inbounds, false))
# meta: location twiceprecision.jl next 187
# meta: location twiceprecision.jl unsafe_getindex 194
u@_6::Int64 = (Base.sub_int)(#temp#@_5::Int64, (Core.getfield)(SSAValue(0), :offset)::Int64)::Int64 # line 195:
SSAValue(2) = (Base.mul_float)((Base.sitofp)(Float64, u@_6::Int64)::Float64, (Core.getfield)((Core.getfield)(SSAValue(0), :step)::Base.TwicePrecision{Float64}, :hi)::Float64)::Float64
SSAValue(3) = (Base.mul_float)((Base.sitofp)(Float64, u@_6::Int64)::Float64, (Core.getfield)((Core.getfield)(SSAValue(0), :step)::Base.TwicePrecision{Float64}, :lo)::Float64)::Float64 # line 196:
# meta: location twiceprecision.jl add2 445
u@_14::Float64 = (Core.getfield)((Core.getfield)(SSAValue(0), :ref)::Base.TwicePrecision{Float64}, :hi)::Float64
v::Float64 = SSAValue(2)
SSAValue(7) = (Base.select_value)((Base.lt_float)((Base.abs_float)(u@_14::Float64)::Float64, (Base.abs_float)(v::Float64)::Float64)::Bool, (Core.tuple)(v::Float64, u@_14::Float64)::Tuple{Float64,Float64}, (Core.tuple)(u@_14::Float64, v::Float64)::Tuple{Float64,Float64})::Tuple{Float64,Float64}
SSAValue(10) = (Base.getfield)(SSAValue(7), 1)::Float64
u@_14::Float64 = SSAValue(10)
SSAValue(12) = (Base.getfield)(SSAValue(7), 2)::Float64
v::Float64 = SSAValue(12) # line 446:
w::Float64 = (Base.add_float)(u@_14::Float64, v::Float64)::Float64
# meta: pop location
SSAValue(15) = (Base.add_float)((Base.sub_float)(u@_14::Float64, w::Float64)::Float64, v::Float64)::Float64
# meta: pop location
# meta: pop location
$(Expr(:inbounds, :pop))
SSAValue(24) = (Base.add_float)(w::Float64, (Base.add_float)(SSAValue(15), (Base.add_float)(SSAValue(3), (Core.getfield)((Core.getfield)(SSAValue(0), :ref)::Base.TwicePrecision{Float64}, :lo)::Float64)::Float64)::Float64)::Float64
SSAValue(25) = (Base.add_int)(#temp#@_5::Int64, 1)::Int64
i::Float64 = SSAValue(24)
#temp#@_5::Int64 = SSAValue(25) # line 3:
SSAValue(26) = i::Float64
SSAValue(27) = Float64
$(Expr(:inbounds, false))
# meta: location coreio.jl println 5
SSAValue(19) = (Core.typeassert)(Base.STDOUT, Base.IO)::IO
SSAValue(21) = SSAValue(26)
SSAValue(22) = " "
SSAValue(23) = SSAValue(27)
# meta: pop location
$(Expr(:inbounds, :pop))
(Base.print)(SSAValue(19), SSAValue(21), SSAValue(22), SSAValue(23), $(QuoteNode('\n')))::Void
44:
goto 3
46:
return
end::Void
julia> @code_warntype cwt(Int32(0), Int32(3))
Variables:
#self# <optimized out>
a::Int32
b::Int32
i::Float64
#temp#@_5::Int64
u@_6::Int64
shift_hi <optimized out>
shift_lo <optimized out>
x_hi <optimized out>
x_lo <optimized out>
#temp#@_11 <optimized out>
#temp#@_12 <optimized out>
w::Float64
u@_14::Float64
v::Float64
Body:
begin
SSAValue(0) = $(Expr(:invoke, MethodInstance for linspace(::Type{Float64}, ::Int32, ::Int32, ::Int64, ::Int64), :(Base.linspace), :(Base.Float64), :(a), :(b), 4, 1))
#temp#@_5::Int64 = 1
3:
unless (Base.not_int)((Base.slt_int)((Core.getfield)(SSAValue(0), :len)::Int64, #temp#@_5::Int64)::Bool)::Bool goto 46
$(Expr(:inbounds, false))
# meta: location twiceprecision.jl next 187
# meta: location twiceprecision.jl unsafe_getindex 194
u@_6::Int64 = (Base.sub_int)(#temp#@_5::Int64, (Core.getfield)(SSAValue(0), :offset)::Int64)::Int64 # line 195:
SSAValue(2) = (Base.mul_float)((Base.sitofp)(Float64, u@_6::Int64)::Float64, (Core.getfield)((Core.getfield)(SSAValue(0), :step)::Base.TwicePrecision{Float64}, :hi)::Float64)::Float64
SSAValue(3) = (Base.mul_float)((Base.sitofp)(Float64, u@_6::Int64)::Float64, (Core.getfield)((Core.getfield)(SSAValue(0), :step)::Base.TwicePrecision{Float64}, :lo)::Float64)::Float64 # line 196:
# meta: location twiceprecision.jl add2 445
u@_14::Float64 = (Core.getfield)((Core.getfield)(SSAValue(0), :ref)::Base.TwicePrecision{Float64}, :hi)::Float64
v::Float64 = SSAValue(2)
SSAValue(7) = (Base.select_value)((Base.lt_float)((Base.abs_float)(u@_14::Float64)::Float64, (Base.abs_float)(v::Float64)::Float64)::Bool, (Core.tuple)(v::Float64, u@_14::Float64)::Tuple{Float64,Float64}, (Core.tuple)(u@_14::Float64, v::Float64)::Tuple{Float64,Float64})::Tuple{Float64,Float64}
SSAValue(10) = (Base.getfield)(SSAValue(7), 1)::Float64
u@_14::Float64 = SSAValue(10)
SSAValue(12) = (Base.getfield)(SSAValue(7), 2)::Float64
v::Float64 = SSAValue(12) # line 446:
w::Float64 = (Base.add_float)(u@_14::Float64, v::Float64)::Float64
# meta: pop location
SSAValue(15) = (Base.add_float)((Base.sub_float)(u@_14::Float64, w::Float64)::Float64, v::Float64)::Float64
# meta: pop location
# meta: pop location
$(Expr(:inbounds, :pop))
SSAValue(24) = (Base.add_float)(w::Float64, (Base.add_float)(SSAValue(15), (Base.add_float)(SSAValue(3), (Core.getfield)((Core.getfield)(SSAValue(0), :ref)::Base.TwicePrecision{Float64}, :lo)::Float64)::Float64)::Float64)::Float64
SSAValue(25) = (Base.add_int)(#temp#@_5::Int64, 1)::Int64
i::Float64 = SSAValue(24)
#temp#@_5::Int64 = SSAValue(25) # line 3:
SSAValue(26) = i::Float64
SSAValue(27) = Float64
$(Expr(:inbounds, false))
# meta: location coreio.jl println 5
SSAValue(19) = (Core.typeassert)(Base.STDOUT, Base.IO)::IO
SSAValue(21) = SSAValue(26)
SSAValue(22) = " "
SSAValue(23) = SSAValue(27)
# meta: pop location
$(Expr(:inbounds, :pop))
(Base.print)(SSAValue(19), SSAValue(21), SSAValue(22), SSAValue(23), $(QuoteNode('\n')))::Void
44:
goto 3
46:
return
end::Void
julia> versioninfo()
Julia Version 0.6.1
Commit 0d7248e* (2017-10-24 22:15 UTC)
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: AMD Ryzen Threadripper 1950X 16-Core Processor
WORD_SIZE: 64
BLAS: libopenblas (ZEN)
LAPACK: liblapack
LIBM: libopenlibm
LLVM: libLLVM-3.9.1 (ORCJIT, generic)
Other tests confirmed that allocations sky rocketed and performance plummeted when passing Float32 arguments. In all my tests, the type seemed to be stable and:
julia> eltype(linspace(0f0, 3f0, 4))
Float32
works as expected.
I could not reproduce on a 1 day old master; inference seems to have been fixed:
julia> function cwt(a, b)
for i β linspace(a, b, 4)
println(i, " ", typeof(i))
end
end
cwt (generic function with 1 method)
julia> cwt(0f0, 3f0)
0.0 Float32
1.0 Float32
2.0 Float32
3.0 Float32
julia> @code_warntype cwt(0f0, 3f0)
Variables:
a::Float32
b::Float32
#temp#@_4::Int64
i::Float32
#temp#@_6::Int64
#temp#@_7::Bool
#temp#@_8::Tuple{Float32,Int64}
Body:
begin
SSAValue(0) = $(Expr(:invoke, MethodInstance for linspace(::Float32, ::Float32, ::Int64), :(Main.linspace), :(a), :(b), 4))::Union{StepRangeLen{Float32,Base.TwicePrecision{Float32},Base.TwicePrecision{Float32}}, StepRangeLen{Float32,Float64,Float64}}
unless (SSAValue(0) isa StepRangeLen{Float32,Base.TwicePrecision{Float32},Base.TwicePrecision{Float32}})::Bool goto 5
#temp#@_6::Int64 = $(Expr(:invoke, MethodInstance for start(::StepRangeLen{Float32,Base.TwicePrecision{Float32},Base.TwicePrecision{Float32}}), :(Base.start), SSAValue(0)))::Int64
goto 13
5:
unless (SSAValue(0) isa StepRangeLen{Float32,Float64,Float64})::Bool goto 9
#temp#@_6::Int64 = $(Expr(:invoke, MethodInstance for start(::StepRangeLen{Float32,Float64,Float64}), :(Base.start), SSAValue(0)))::Int64
goto 13
9:
goto 11
11:
(Base.error)("fatal error in type inference (type bound)")::Any
13:
#temp#@_4::Int64 = #temp#@_6::Int64
15:
unless (SSAValue(0) isa StepRangeLen{Float32,Base.TwicePrecision{Float32},Base.TwicePrecision{Float32}})::Bool goto 19
#temp#@_7::Bool = $(Expr(:invoke, MethodInstance for done(::StepRangeLen{Float32,Base.TwicePrecision{Float32},Base.TwicePrecision{Float32}}, ::Int64), :(Base.done), SSAValue(0), :(#temp#@_4)))::Bool
goto 27
19:
unless (SSAValue(0) isa StepRangeLen{Float32,Float64,Float64})::Bool goto 23
#temp#@_7::Bool = $(Expr(:invoke, MethodInstance for done(::StepRangeLen{Float32,Float64,Float64}, ::Int64), :(Base.done), SSAValue(0), :(#temp#@_4)))::Bool
goto 27
23:
goto 25
25:
(Base.error)("fatal error in type inference (type bound)")::Any
27:
unless (Base.not_int)(#temp#@_7::Bool)::Bool goto 48
unless (SSAValue(0) isa StepRangeLen{Float32,Base.TwicePrecision{Float32},Base.TwicePrecision{Float32}})::Bool goto 32
#temp#@_8::Tuple{Float32,Int64} = $(Expr(:invoke, MethodInstance for next(::StepRangeLen{Float32,Base.TwicePrecision{Float32},Base.TwicePrecision{Float32}}, ::Int64), :(Base.next), SSAValue(0), :(#temp#@_4)))::Tuple{Float32,Int64}
goto 40
32:
unless (SSAValue(0) isa StepRangeLen{Float32,Float64,Float64})::Bool goto 36
#temp#@_8::Tuple{Float32,Int64} = $(Expr(:invoke, MethodInstance for next(::StepRangeLen{Float32,Float64,Float64}, ::Int64), :(Base.next), SSAValue(0), :(#temp#@_4)))::Tuple{Float32,Int64}
goto 40
36:
goto 38
38:
(Base.error)("fatal error in type inference (type bound)")::Any
40:
SSAValue(1) = #temp#@_8::Tuple{Float32,Int64}
i::Float32 = (Core.getfield)(SSAValue(1), 1)::Float32
#temp#@_4::Int64 = (Core.getfield)(SSAValue(1), 2)::Int64
#= line 3 =#
$(Expr(:invoke, MethodInstance for println(::Float32, ::String, ::Vararg{Any,N} where N), :(Main.println), :(i), " ", Float32))::Void
46:
goto 15
48:
return
end::Void
julia> versioninfo()
Julia Version 0.7.0-DEV.2583
Commit 80d8719 (2017-11-22 18:20 UTC)
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: AMD Ryzen Threadripper 1950X 16-Core Processor
WORD_SIZE: 64
BLAS: libopenblas (ZEN)
LAPACK: liblapack
LIBM: libopenlibm
LLVM: libLLVM-3.9.1 (ORCJIT, znver1)
Environment: