使用 Numba 将数组上的调用函数转移到 GPU

问题描述 投票:0回答:1

我不认为我们可以从 GPU 打印任何东西,因为在

print
函数中调用
@cuda.jit
不起作用,但后来我尝试调用
A.shape
看看会发生什么。

import numpy as np
from numba import  cuda

A = np.random.randn(1000, 1000)
A_gpu = cuda.to_device(A)
A_gpu.shape
(1000, 1000)
A_gpu[0][0]
0.4253498653987585
A_gpu.T
<numba.cuda.cudadrv.devicearray.DeviceNDArray at 0x7f5de810ffa0>

要打印到控制台,是否需要先将数字复制到 CPU?

%timeit A.T
%timeit A_gpu.T
%timeit A.shape
%timeit A_gpu.shape
%timeit A[0][0]
%timeit A_gpu[0][0]
132 ns ± 18.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
159 ms ± 29.3 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
*76 ns* ± 2.37 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
*47.8 ns* ± 8.81 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
376 ns ± 146 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
161 µs ± 25.7 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

调用

A.shape
由于某种原因在 GPU 中更快,但其他功能更慢。但是,访问
A[i, j]
中的元素
@cuda.jit
可能是经过优化的并且并不慢。

我正在实现一个用于矩阵乘法CUDA内核,目的是将其用于神经网络中的反向传播,这意味着

dL_dX = np.dot(dL_dY, self.weights.T)
将经常执行。

如果我需要转置矩阵,我想知道从 GPU 转置是否是不好的做法

matrix_multiplication_gpu[blocks_per_grid, threads_per_block](A_gpu, B_gpu.T)
以及先在 CPU 中转置矩阵,然后将结果移动/“缓存”到 GPU 是否更好
cuda.to_device(A.T)
。有趣的是,将数组移动到 GPU
%timeit cuda.to_device(A.T)
比在 GPU 内转置数组快得多
2.41 ms ± 145 µs

python numpy cuda numba
1个回答
0
投票

Numba gpu 阵列 transpose 运行一个 GPU 内核。这就是为什么它比 numpy 慢的原因,numpy generally 只是改变步幅而不触及底层数据。

执行涉及一个或多个转置矩阵(可追溯到 Linpack 和 BLAS 的起源)的点积的规范方法是更改算法以处理以转置顺序读取输入,而不是在执行之前实际转置输入数据产品运营。

© www.soinside.com 2019 - 2024. All rights reserved.