最近,我一直在尝试使用 Numba 库在 Python 中进行 GPU 编程。我一直在使用那里的教程在他们的网站上阅读它,目前我陷入了他们的示例,可以在这里找到:https: //numba.pydata.org/numba-doc/latest/cuda/examples。 html。我试图稍微概括一下快速矩阵乘法的示例(其形式为 A*B=C)。在测试时,我注意到尺寸不能完全被每块线程数 (TPB) 整除的矩阵不会产生正确的答案。
我从https://numba.pydata.org/numba-doc/latest/cuda/examples.html的示例中复制了下面的代码,并创建了一个带有 4 x 4 矩阵的非常小的测试用例。如果我选择 TPB=2 一切都很好,但是当我设置 TPB=3 时就会出错。我知道代码超出了矩阵的范围,但我无法阻止这种情况发生(我在ty + i * TPB和tx + i * TPB上尝试了一些 if 语句,但这些不起作用。
from numba import cuda, float32
import numpy as np
import math
@cuda.jit
def fast_matmul(A, B, C):
# Define an array in the shared memory
# The size and type of the arrays must be known at compile time
sA = cuda.shared.array(shape=(TPB, TPB), dtype=float32)
sB = cuda.shared.array(shape=(TPB, TPB), dtype=float32)
x, y = cuda.grid(2)
tx = cuda.threadIdx.x
ty = cuda.threadIdx.y
bpg = cuda.gridDim.x # blocks per grid
if x >= C.shape[0] and y >= C.shape[1]:
# Quit if (x, y) is outside of valid C boundary
return
# Each thread computes one element in the result matrix.
# The dot product is chunked into dot products of TPB-long vectors.
tmp = 0.
for i in range(bpg):
# Preload data into shared memory
sA[tx, ty] = A[x, ty + i * TPB]
sB[tx, ty] = B[tx + i * TPB, y]
# Wait until all threads finish preloading
cuda.syncthreads()
# Computes partial product on the shared memory
for j in range(TPB):
tmp += sA[tx, j] * sB[j, ty]
# Wait until all threads finish computing
cuda.syncthreads()
C[x, y] = tmp
#%%
x_h = np.arange(16).reshape([4,4])
y_h = np.ones([4,4])
z_h = np.zeros([4,4])
x_d = cuda.to_device(x_h)
y_d = cuda.to_device(y_h)
z_d = cuda.to_device(z_h)
我想编写一些不依赖于尺寸可以被 TPB 整除的矩阵 A、B 和 C 的代码,因为这些有时超出了我的控制范围。据我所知,GPU 仅在对非常大的矩阵进行矩阵乘法时速度更快,但我想使用小示例来检查答案是否正确,然后再将其应用于实际数据。
慕婉清6462132
相关分类