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

How do I access an element in a CuArray of Julia and change its value?

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

using Flux, CuArrays

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

因为allowscalar设置为false,自然会出现下图

ERROR: scalar setindex! is disallowed

但是如果去掉allowscalar,就会出现下面的样子

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 中的元素并更改其值? 期待您的回音。

I turned "allowscalar" on and off before and after the part that accesses the element. Then, it was about 20 times slower than when "allowscalar" was set to true.

切换allowscalar 应该不会影响性能。事实上,当 CuArrays 需要使用某些 API 检查单个元素时,它本身就会这样做。该函数的宏版本可以很容易地做到这一点:

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

感谢您的回答。但是我有一个问题。 maleadt 先生说 "Toggling allowscalar should not affect performance. " 但是,在我的程序里,好像有点不一样。

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)

为什么会这样?