朱莉娅(Julia)中具有容器类型和矩阵向量乘积的类型稳定性

凯文·L·凯斯

我正在尝试将Julia'sA_mul_B!与容器类型配合使用,例如

# my composite type, contains 2 vectors and 1 matrix of same Float type
type MyContainer{T <: Float}
    z :: Vector
    x :: Matrix
    y :: Vector
    MyContainer(z::Vector{T}, x::Matrix{T}, y::Vector{T}) = new(z,x,y) 
end

然后,我使用MyContainerwith的实例,A_mul_B!然后对Vector对象进行一些算术运算

# only work with single/double precision
typealias Float Union{Float32, Float64}

# function to perform mat-vec multiply
function f{T <: Float}(v::MyContainer{T}) 
    Base.A_mul_B!(v.z, v.x, v.y)
    return sumabs2(v.z) * sumabs2(v.y)
end

正如定义的f那样,即使构造函数本身是类型稳定的,它也不是类型稳定的。是否有一个地方我可以注释类型的地方zx以及yA_mul_B!看到他们?

这是一个最小的工作示例:

MyModule.jl

module MyModule

export MyContainer, f

# only work with single/double precision
typealias Float Union{Float32, Float64}

# my composite type, contains 2 vectors and 1 matrix of same Float type
type MyContainer{T <: Float}
    z :: Vector
    x :: Matrix
    y :: Vector
    MyContainer(z::Vector{T}, x::Matrix{T}, y::Vector{T}) = new(z,x,y) 
end

# testing routine initializes all arrays with a single value 
function MyContainer{T <: Float}(n::Int, t::T)
    z = t*ones(T, n)
    x = t*ones(T, (n,n))
    y = t*ones(T, n)
    return MyContainer{eltype(z)}(z, x, y)
end

# function to perform mat-vec multiply
function f{T <: Float}(v::MyContainer{T}) 
    Base.A_mul_B!(v.z, v.x, v.y)
    return sumabs2(v.z) * sumabs2(v.y)
end

end

test.jl

include("MyModule.jl")

function g() 
    # check type stability
    @code_warntype MyModule.MyContainer(10, 1.0) # type-stable
    @code_warntype MyModule.f(v) # red Array{T,1}, Array{T,2}, Any

    # make a container
    v = MyModule.MyContainer(10, 1.0)

    # does type-stability matter for performance?
    @time 1+1 
    MyModule.f(v)
    @time MyModule.f(v) # maybe... note small memory allocation
end

g()

部分输出

# omit output of @code_warntype for conciseness
  0.000000 seconds
  0.000001 seconds (3 allocations: 48 bytes)
10000.0
Fengyang Wang

正如大卫·桑德斯(David Sanders)指出的那样,问题是

type MyContainer{T <: Float}
    z :: Vector
    x :: Matrix
    y :: Vector
    MyContainer(z::Vector{T}, x::Matrix{T}, y::Vector{T}) = new(z,x,y) 
end

由于VectorMatrix是抽象类型,因此该类型的字段不可具体推断。解决方法是具体键入它们:

type MyContainer{T <: Float}
    z :: Vector{T}
    x :: Matrix{T}
    y :: Vector{T}
end

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章