什么是openCL等效的这个cuda“cudaMallocPitch”代码。?

时间:2012-04-24 06:30:38

标签: visual-c++ opencl gpu amd-processor

我的电脑配有AMD处理器和ATI 3200 GPU,不支持OpenCL。其余的代码都是通过“回退到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);

overhere。它会给出错误,如

  

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

按下休息时,它会给出:

  

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

调试时

在调用堆栈中,它显示:

  

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

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

1 个答案:

答案 0 :(得分:3)

首先,在CUDA代码中,你正在做一个非常低效的复制数据。 CUDA运行时具有函数cudaMemcpy2D,它通过循环遍历不同的行来完成您正在尝试执行的操作。

cudaMallocPitch做的是计算最佳音高(= 2D数组中行之间的字节距离),这样每个新行都从一个最适合合并的地址开始,然后分配一个内存区域作为大小作为音高乘以指定的行数。您可以通过首先计算最佳音高然后分配正确的音量来模拟OpenCL中的相同内容。

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

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

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