gpt4 book ai didi

types - 函数向输入参数添加维度时的类型稳定性问题

转载 作者:行者123 更新时间:2023-12-01 13:22:58 27 4
gpt4 key购买 nike

我有一个函数返回一个数组,该数组的元素类型与输入数组相同,但多了一个维度。这是一个简单的例子:

function myfun(a::Array{T,N}) where {T,N}
b = Array{T,N+1}(size(a)...,2)
b[:] = 42
return b
end

当在 2x2 数组上调用此函数时,它返回一个 2x2x2 数组。

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_warntypebAny 类型。

即使在 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_warntype myfun(zeros(2,2)) 现在返回 Array{Float64,_} 其中 _b 的类型.当输入参数有 2 个维度时,Julia 是否应该无法计算出维度数为 3?

我正在使用 julia 0.6.2(在 Linux 上)。

最佳答案

这是因为构造函数(Array{T,N+1}(size(a)...,2))是在运行时执行的,你可以使用@generated functions在编译时预先计算 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

关于types - 函数向输入参数添加维度时的类型稳定性问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49026708/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com