Types 函数向输入参数添加维度时的类型稳定性问题
我有一个函数,它返回的数组的元素类型与输入数组相同,但有一个额外的维度。 下面是一个简单的例子:Types 函数向输入参数添加维度时的类型稳定性问题,types,julia,generic-programming,Types,Julia,Generic Programming,我有一个函数,它返回的数组的元素类型与输入数组相同,但有一个额外的维度。 下面是一个简单的例子: function myfun(a::Array{T,N}) where {T,N} b = Array{T,N+1}(size(a)...,2) b[:] = 42 return b end 在2x2数组上调用此函数时,它将返回2x2数组 myfun(zeros(2,2)) 2×2×2 Array{Float64,3}: [:, :, 1] = 42.0 42.0 42.0
function myfun(a::Array{T,N}) where {T,N}
b = Array{T,N+1}(size(a)...,2)
b[:] = 42
return b
end
在2x2数组上调用此函数时,它将返回2x2数组
myfun(zeros(2,2))
2×2×2 Array{Float64,3}:
[:, :, 1] =
42.0 42.0
42.0 42.0
[:, :, 2] =
42.0 42.0
42.0 42.0
但是,此函数的类型不稳定。根据@code\u warntype
,b
属于Any
类型
即使使用b
上的类型注释,结果也不是类型稳定的
关于尺寸的数量:
function myfun(a::Array{T,N}) where {T,N}
b = Array{T,N+1}(size(a)...,2) :: Array{T,N+1}
b[:] = T(42)
return b
end
@code\u warntype myfun(零(2,2))
现在返回b
类型的数组{Float64,{u},其中。当输入参数有两个维度时,Julia是否应该不能计算出维度数是3
我使用的是julia 0.6.2(在linux上)。这是因为构造函数(
数组{T,N+1}(大小(a)…,2)
)是在运行时执行的,您可以使用它在编译时预计算N
:
julia> @generated function myfun(a::Array{T,N}) where {T,N}
NN = N+1
quote
b = Array{$T,$NN}(size(a)...,2)
b[:] = 42
return b
end
end
myfun (generic function with 1 method)
julia> @code_warntype myfun(zeros(2,2))
Variables:
#self# <optimized out>
a::Array{Float64,2}
b::Array{Float64,3}
Body:
begin # line 2:
# meta: location REPL[1] # line 4:
SSAValue(2) = (Base.arraysize)(a::Array{Float64,2}, 1)::Int64
SSAValue(1) = (Base.arraysize)(a::Array{Float64,2}, 2)::Int64
b::Array{Float64,3} = $(Expr(:foreigncall, :(:jl_alloc_array_3d), Array{Float64,3}, svec(Any, Int64, Int64, Int64), Array{Float64,3}, 0, SSAValue(2), 0, SSAValue(1), 0, :($(QuoteNode(2))), 0)) # line 5:
$(Expr(:invoke, MethodInstance for fill!(::Array{Float64,3}, ::Int64), :(Base.fill!), :(b), 42))
# meta: pop location
return b::Array{Float64,3}
end::Array{Float64,3}
julia> myfun(zeros(2,2))
2×2×2 Array{Float64,3}:
[:, :, 1] =
42.0 42.0
42.0 42.0
[:, :, 2] =
42.0 42.0
42.0 42.0
julia>@生成函数myfun(a::数组{T,N}),其中{T,N}
NN=N+1
引用
b=数组{$T,$NN}(大小(a)…,2)
b[:]=42
返回b
结束
结束
myfun(具有1个方法的通用函数)
julia>@code_warntype myfun(零(2,2))
变量:
#自我#
a::数组{Float64,2}
b::数组{Float64,3}
正文:
开始#第2行:
#meta:location REPL[1]#第4行:
SSAValue(2)=(Base.arraysize)(a::数组{Float64,2},1)::Int64
SSAValue(1)=(Base.arraysize)(a::数组{Float64,2},2)::Int64
数组{Float64,3}=$(Expr(:foreigncall,:(:jl_alloc_Array_3d),数组{Float64,3},svec(Any,Int64,Int64,Int64,Int64),数组{Float64,3},0,SSAValue(2),0,SSAValue(1),0,:($(QuoteNode(2)),0))#第5行:
$(Expr(:invoke,MethodInstance for fill!(::数组{Float64,3},::Int64),:(Base.fill!),:(b),42))
#梅塔:流行位置
返回b::数组{Float64,3}
结束::数组{Float64,3}
julia>myfun(零(2,2))
2×2×2数组{Float64,3}:
[:, :, 1] =
42.0 42.0
42.0 42.0
[:, :, 2] =
42.0 42.0
42.0 42.0