- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试使用 NumbaPro 的 cuda 扩展来乘以大型数组矩阵。最后我想要的是将大小为 NxN 的矩阵乘以一个对角矩阵,该矩阵将作为一维矩阵输入(因此,我发现 a.dot(numpy.diagflat(b)) 与* b).但是,我收到一个不提供任何信息的断言错误。
如果我将两个一维数组矩阵相乘,我只能避免这个断言错误,但这不是我想要做的。
from numbapro import vectorize, cuda
from numba import f4,f8
import numpy as np
def generate_input(n):
import numpy as np
A = np.array(np.random.sample((n,n)))
B = np.array(np.random.sample(n) + 10)
return A, B
def product(a, b):
return a * b
def main():
cu_product = vectorize([f4(f4, f4), f8(f8, f8)], target='gpu')(product)
N = 1000
A, B = generate_input(N)
D = np.empty(A.shape)
stream = cuda.stream()
with stream.auto_synchronize():
dA = cuda.to_device(A, stream)
dB = cuda.to_device(B, stream)
dD = cuda.to_device(D, stream, copy=False)
cu_product(dA, dB, out=dD, stream=stream)
dD.to_host(stream)
if __name__ == '__main__':
main()
这是我的终端输出的内容:
Traceback (most recent call last):
File "cuda_vectorize.py", line 32, in <module>
main()
File "cuda_vectorize.py", line 28, in main
cu_product(dA, dB, out=dD, stream=stream)
File "/opt/anaconda1anaconda2anaconda3/lib/python2.7/site-packages/numbapro/_cudadispatch.py", line 109, in __call__
File "/opt/anaconda1anaconda2anaconda3/lib/python2.7/site-packages/numbapro/_cudadispatch.py", line 191, in _arguments_requirement
AssertionError
最佳答案
问题是您正在对采用非标量参数的函数使用 vectorize
。 NumbaPro 的vectorize
的想法是,它将标量函数作为输入,并生成一个将标量运算并行应用于向量的所有元素的函数。请参阅 NumbaPro documentation。
你的函数接受一个矩阵和一个向量,它们绝对不是标量。 [编辑] 您可以使用 NumbaPro 的 cuBLAS 包装器或编写您自己的简单内核函数在 GPU 上做您想做的事。这是一个演示两者的示例。注意将需要 NumbaPro 0.12.2 或更高版本(在此编辑时刚刚发布)。
from numbapro import jit, cuda
from numba import float32
import numbapro.cudalib.cublas as cublas
import numpy as np
from timeit import default_timer as timer
def generate_input(n):
A = np.array(np.random.sample((n,n)), dtype=np.float32)
B = np.array(np.random.sample(n), dtype=A.dtype)
return A, B
@cuda.jit(argtypes=[float32[:,:], float32[:,:], float32[:]])
def diagproduct(c, a, b):
startX, startY = cuda.grid(2)
gridX = cuda.gridDim.x * cuda.blockDim.x;
gridY = cuda.gridDim.y * cuda.blockDim.y;
height, width = c.shape
for y in range(startY, height, gridY):
for x in range(startX, width, gridX):
c[y, x] = a[y, x] * b[x]
def main():
N = 1000
A, B = generate_input(N)
D = np.empty(A.shape, dtype=A.dtype)
E = np.zeros(A.shape, dtype=A.dtype)
F = np.empty(A.shape, dtype=A.dtype)
start = timer()
E = np.dot(A, np.diag(B))
numpy_time = timer() - start
blas = cublas.api.Blas()
start = timer()
blas.gemm('N', 'N', N, N, N, 1.0, np.diag(B), A, 0.0, D)
cublas_time = timer() - start
diff = np.abs(D-E)
print("Maximum CUBLAS error %f" % np.max(diff))
blockdim = (32, 8)
griddim = (16, 16)
start = timer()
dA = cuda.to_device(A)
dB = cuda.to_device(B)
dF = cuda.to_device(F, copy=False)
diagproduct[griddim, blockdim](dF, dA, dB)
dF.to_host()
cuda_time = timer() - start
diff = np.abs(F-E)
print("Maximum CUDA error %f" % np.max(diff))
print("Numpy took %f seconds" % numpy_time)
print("CUBLAS took %f seconds, %0.2fx speedup" % (cublas_time, numpy_time / cublas_time))
print("CUDA JIT took %f seconds, %0.2fx speedup" % (cuda_time, numpy_time / cuda_time))
if __name__ == '__main__':
main()
内核明显更快,因为 SGEMM 执行全矩阵乘法 (O(n^3)),并将对角线扩展为全矩阵。 diagproduct
函数更智能。它只是对每个矩阵元素进行一次乘法运算,而不会将对角线扩展为完整矩阵。以下是 N=1000 在我的 NVIDIA Tesla K20c GPU 上的结果:
Maximum CUBLAS error 0.000000
Maximum CUDA error 0.000000
Numpy took 0.024535 seconds
CUBLAS took 0.010345 seconds, 2.37x speedup
CUDA JIT took 0.004857 seconds, 5.05x speedup
时间包括进出 GPU 的所有副本,这对于小型矩阵来说是一个严重的瓶颈。如果我们将 N 设置为 10,000 并再次运行,我们将获得更大的加速:
Maximum CUBLAS error 0.000000
Maximum CUDA error 0.000000
Numpy took 7.245677 seconds
CUBLAS took 1.371524 seconds, 5.28x speedup
CUDA JIT took 0.264598 seconds, 27.38x speedup
然而,对于非常小的矩阵,CUBLAS SGEMM 具有优化路径,因此更接近 CUDA 性能。这里,N=100
Maximum CUBLAS error 0.000000
Maximum CUDA error 0.000000
Numpy took 0.006876 seconds
CUBLAS took 0.001425 seconds, 4.83x speedup
CUDA JIT took 0.001313 seconds, 5.24x speedup
关于python - Anaconda 的 NumbaPro CUDA 断言错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17153985/
我正在比较几个 Python 模块/扩展或方法来实现以下目标: import numpy as np def fdtd(input_grid, steps): grid = input_gri
我正在寻找一种将 JIT 用于 python 类构造函数的方法,如下所示: import numpy as np from numbapro import jit, autojit from time
import numpy import numpy as np from numbapro import cuda @cuda.autojit def foo(aryA, aryB,out):
谁能向我解释一下为什么每次我运行这段代码时我的电脑都会死机? from numbapro import cuda import numpy as np from timeit import defau
我正在尝试运行以下程序: import numpy as np from timeit import default_timer as timer from numbapro import vecto
我正在尝试使用作业设置 3D 循环 C(i,j,k) = A(i,j,k) + B(i,j,k) 在我的 GPU 上使用 Python。这是我的 GPU: http://www.geforce.co
我正在尝试使用 NumbaPro 的 cuda 扩展来乘以大型数组矩阵。最后我想要的是将大小为 NxN 的矩阵乘以一个对角矩阵,该矩阵将作为一维矩阵输入(因此,我发现 a.dot(numpy.diag
总体目标是使用NumbaPro在 GPU 上运行某些功能(在 OSX 10.8.3 上)。 在开始之前,我只是想把一切都设置好。根据this page我安装了 CUDA,注册为 CUDA 开发人员,下
我正在使用 Python/NumbaPro 在 Windows 机器上使用我的 CUDA 兼容 GPU。我使用 Cygwin 作为 shell,并且在 cygwin 控制台中可以毫无问题地找到我的 C
我是 CUDA 的新手,我想知道是否 PyCUDA (free)或 NumbaPro CUDA Python (不是免费的)对我来说更好(假设图书馆费用不是问题)。 两者似乎都要求您使用各自的 Pyt
我想使用 Numbapro API 在 python 中执行 CUDA 内核。我有这段代码: import math import numpy from numbapro import jit, cu
我是一名优秀的程序员,十分优秀!