0

我的 PC 有一个 AMD 处理器和一个不支持 OpenCL 的 ATI 3200 GPU。其余代码全部通过“回退到 CPU 本身”运行。

我正在将其中一个代码从 CUDA 转换为 OpenCL,但停留在 OpenCL 中没有确切转换代码的某些特定部分。因为我在 OpenCL 方面的经验较少,所以我无法弄清楚这一点,如果你们中的任何人认为可行,请建议我一些解决方案,

CUDA 代码是,

size_t pitch = 0;   
cudaError error = cudaMallocPitch((void**)&gpu_data, (size_t*)&pitch, 
                          instances->cols * sizeof(float), instances->rows);

for( int i = 0; i < instances->rows; i++ ){ 
    error = cudaMemcpy((void*)(gpu_data + (pitch/sizeof(float))*i), 
                       (void*)(instances->data + (instances->cols*i)), 
                       instances->cols * sizeof(float) ,cudaMemcpyHostToDevice);

如果我从上面删除音高值,我最终会遇到一个不写入设备内存“gpu_data”的问题。

有人请将此代码转换为 OpenCL 并回复。我已将其转换为 OpenCL,但它无法正常工作并且数据未写入“gpu_data”。我转换后的 OpenCL 代码是

gpu_data = clCreateBuffer(context, CL_MEM_READ_WRITE, ((instances->cols)*(instances->rows))*sizeof(float), NULL, &ret);
for( int i = 0; i < instances->rows; i++ ){ 
    ret = clEnqueueWriteBuffer(command_queue, gpu_data, CL_TRUE, 0, ((instances->cols)*(instances->rows))*sizeof(float),(void*)(instances->data + (instances->cols*i)) , 0, NULL, NULL);

有时它在这段代码中运行良好并且卡在阅读部分,即

ret = clEnqueueReadBuffer(command_queue, gpu_data, CL_TRUE, 0,sizeof( float ) * instances->cols* 1 , instances->data, 0, NULL, NULL);

这边。它给出了类似的错误

CL_kmeans.exe 中 0x10001098 处的未处理异常:0xC000001D:非法指令。

当按下 break 时,它给出:

没有为任何调用堆栈帧加载符号。无法显示源代码。

调试时。在调用堆栈中显示:

OCL8CA9.tmp.dll!10001098()
[下面的帧可能不正确和/或丢失,没有为 OCL8CA9.tmp.dll 加载符号]
amdocl.dll!5c39de16()

我真的不知道这意味着什么。有人请帮我解决这个问题。

4

1 回答 1

4

首先,在 CUDA 代码中,复制数据的效率非常低。CUDA 运行时具有cudaMemcpy2D通过循环遍历不同行来执行您尝试执行的操作的功能。

什么cudaMallocPitch是计算最佳间距(= 2D 数组中行之间的字节距离),使得每个新行都从一个最适合合并的地址开始,然后分配一个内存区域,该内存区域与间距乘以行数一样大你指定。您可以在 OpenCL 中模拟同样的事情,首先计算最佳音高,然后分配正确的尺寸。

最佳间距通过 (1) 获取卡的基地址对齐首选项来计算(使用 clGetDeviceInfo 的 CL_DEVICE_MEM_BASE_ADDR_ALIGN 属性:请注意,返回值以位为单位,因此您必须除以 8 才能以字节为单位);让我们称之为(2)找到不小于自然数据间距base的最大倍数(sizeof(type)乘以列数);base这将是你的pitch

然后,您分配pitch行字节数,并将pitch信息传递给内核。

此外,当将数据从主机复制到设备时,您希望使用clEnqueue{Read,Write}BufferRect专门设计用于复制 2D 数据的 (它们是 的对应物cudaMemcpy2D)。

于 2012-05-05T18:45:51.220 回答