我是CUDA编程的新手,我开始使用PyCUDA来获得基础知识。我研究了这些教程并运行了几个简单的测试代码。测试仅使用1D阵列。当我尝试使用2D数组运行以下代码时,我不断收到PyCUDA警告,说清理操作由于地址错位而失败。
import pycuda.autoinit
import pycuda.driver as drv
import numpy as np
from pycuda.compiler import SourceModule
mod = SourceModule("""
__global__ void multiply(float **dest) {
const int i = threadIdx.x;
const int j = threadIdx.y;
dest[i][j] = 2.0*dest[i][j];
}
""")
a = np.random.randn(32, 32).astype(np.float32)
multiply = mod.get_function("multiply")
multiply(drv.InOut(a), block=(32,32,1), grid=(1,1))
print(a)
运行上述脚本时出现的错误是:
Traceback (most recent call last):
File "cudaTest.py", line 16, in <module>
multiply(drv.InOut(a), block=(32,32,1), grid=(1,1))
File "/users/gpu/local/python3.3/lib/python3.6/site-packages/pycuda-2016.1.2-py3.6-linux-x86_64.egg/pycuda/driver.py", line 405, in function_call
Context.synchronize()
pycuda._driver.LogicError: cuCtxSynchronize failed: misaligned address
PyCUDA WARNING: a clean-up operation failed (dead context maybe?)
cuMemFree failed: misaligned address
PyCUDA WARNING: a clean-up operation failed (dead context maybe?)
cuModuleUnload failed: misaligned address
我已经检查了有关SO的其他问题并找到了similar one。根据那里给出的答案,我尝试指定数组a
的大小,但无济于事。
我在带有两个nVidia Tesla K10 GPU的群集上运行此功能。由于我没有root访问权限,因此我必须在本地安装Python3并将numpy,pyCUDA等添加到本地安装。该集群在Ubuntu 12.04.1 LTS上运行。我使用Python 3.6.0与PyCUDA 2016.1.2和CUDA 6.0
答案 0 :(得分:3)
这里的问题是你对什么构成一个&#34; 2D阵列&#34;是不正确的。 Numpy数组(以及扩展名为PyCUDA gpuarrays)默认以行主要顺序存储在斜线性存储器中。你的内核已被编写为期望输入中的指针数组,并且正在尝试将浮点数据用作地址,从而导致您看到的运行时寻址错误。
要更正内核以使用数组,您需要将其修改为:
INSERT INTO TABLE_NAME (column1,column2,column3,...columnN)
VALUES (value1,value2,value3,...valueN);
请注意,数组作为指向线性分配的指针传递,而不是行指针数组。因此,您需要将元素中的数组间距传递给内核,以便调用PyCUDA主机代码如下所示:
mod = SourceModule("""
__global__ void multiply(float *dest, int lda) {
const int i = threadIdx.x;
const int j = threadIdx.y;
float *p = &dest[i * lda + j]; // row major order
*p *= 2.0f;
}
""")
您应该会发现现在可以正常使用。