【发布时间】:2020-09-27 17:06:34
【问题描述】:
我有两个相当大的数组,分别是长度为 N 和 M 的元素。对于 N 个元素中的每一个,我需要对 M 个元素中的每一个进行计算,然后减少这些结果以得到另一个长度为 N 的数组。这听起来像是非常适合 GPU 加速的问题类型,我因此想使用 Numba CUDA 来实现它,但我正在努力找出如何处理这个问题的减少部分。 Numba 关于减少的文档https://numba.pydata.org/numba-doc/dev/cuda/reduction.html 仅显示了如何将所有内容减少为一个数字,但我基本上需要减少为一个数组。下面是一个超级简化的例子,基本上我想要实现的目标
from numba import cuda
import numpy as np
@cuda.jit
def processArr(A, B):
i = cuda.grid(1)
if i < A.size:
A[i] = A[i] * B
@cuda.jit
def reduceArr(A, B, C):
i = cuda.grid(1)
if i < A.size:
total = 1
processArr(A[i], B[i])
for j in range(A.shape[1]):
total *= A[i, j]
C[i] = total
a = np.array([[0, 0], [1, 1], [1, 2]])
b = np.array([1, 2, 3])
c = np.zeros(3)
threadsperblock = 32
blockspergrid = math.ceil(b.shape[0] / threadsperblock)
reduceArr[blockspergrid, threadsperblock](a, b, c)
print(c)
这段代码显然没有运行,但希望它说明了我想要实现的目标。
有没有办法使用 Numba 来实现这一点,或者首先尝试在 GPU 上执行缩减步骤是愚蠢的,即最好只在 GPU 上执行 NxM 操作,然后在之后的CPU?
【问题讨论】:
-
是的,你可以用 numba 做到这一点。
N和M的实际大小是多少?对于您在此处显示的尺寸,在 GPU 上执行任何这些操作都没有任何意义。并且根据N的实际大小,在几种不同的策略中选择一种可能会更方便。 -
使用A.size可能是错误的
-
@RobertCrovella 真正的 N 大约为 100,M 大约为 300。实际应用程序还将涉及静态查找表,但其大小取决于用户。它通常可能在 100x100 的数量级
-
@talonmies 这可能是真的,但这段代码无法在“processArr(A[i], B[i])”行编译,因为显然嵌套函数就像我正在做的那样不是正确的方式,但我不确定正确的方式是什么。