如何访问Julia的CuArray中的元素并更改其值?

时间:2020-04-27 11:38:16

标签: julia julia-gpu

我只想更改一个元素,如下面的代码所示。

using Flux, CuArrays

a = rand(3,3) |> gpu
CuArrays.allowscalar(false)
a[1, 1] = 1.0f0

由于allowscalar设置为false,它自然会显示如下。

ERROR: scalar setindex! is disallowed

但是如果删除了allowcalar,它将显示如下。

Performing scalar operations on GPU arrays: This is very slow, consider disallowing these operations with allowscalar(false)

我在访问元素的部分之前和之后打开和关闭“ allowscalar”。 然后,它比将“ allowscalar”设置为true时慢了大约20倍。

接下来,我尝试一次在CPU上创建另一个矩阵,然后在GPU上加总矩阵,如下所示。

b = zeros(Float32, 3, 3)
b[1, 1] = 1.0f0
b = b |> gpu
a .+= b

但是,如果我能像下面这样在GPU上做的话,速度大约要快4倍。

a .*= 1.0f0 # Dummy calculations that do some processing on the GPU
a .+= a # Dummy calculations that do some processing on the GPU

如何访问CuArray中的元素并更改其值? 我期待着您的回音。

2 个答案:

答案 0 :(得分:0)

我在访问元素的部分之前和之后打开和关闭“ allowscalar”。然后,它比将“ allowscalar”设置为true时慢了大约20倍。

切换allowscalar不会影响性能。实际上,当需要使用某些API检查单个元素时,CuArrays便会这样做。该函数的宏版本使操作变得容易:

julia> a = CuArrays.rand(3,3);

julia> CuArrays.allowscalar(false)

julia> a[1, 1] = 1.0f0
ERROR: scalar setindex! is disallowed

julia> CuArrays.@allowscalar a[1, 1] = 1.0f0
1.0f0

julia> a
3×3 CuArray{Float32,2,Nothing}:
 1.0       0.277899   0.333898
 0.126213  0.0881365  0.794662
 0.94518   0.586488   0.656359

julia> a[1, 1] = 1.0f0

答案 1 :(得分:0)

谢谢您的回答。但是我有一个问题。 Maleadt先生说:“切换allowcalar不应影响性能。” 但是,在我的程序中,似乎有些不同。

using Flux, CuArrays, CUDAnative
a = CuArrays.rand(50, 50);
@time for i in 1:10000
    b = sum(CUDAnative.log.(a))
end
12.222549 seconds (4.25 M allocations: 151.379 MiB, 1.05% gc time)

另一方面,

using Flux, CuArrays, CUDAnative
a = CuArrays.rand(50, 50);

CuArrays.allowscalar(false)

@time for i in 1:10000
    CuArrays.@allowscalar b = sum(CUDAnative.log.(a))
end
16.512146 seconds (4.21 M allocations: 151.733 MiB, 0.57% gc time)

为什么会这样?