2012-04-24 75 views
0

我的电脑有一个AMD处理器和一个不支持OpenCL的ATI 3200 GPU。剩下的代码全部由“回退到CPU本身”运行。这个cuda“cudaMallocPitch”代码的openCL等价物是什么?

我将其中一个代码从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:非法指令。

压破时,它给出:

否符号已加载的任何调用堆栈帧。源代码无法显示。

while debugging。在调用栈中它显示:

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

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

回答

3

首先,在CUDA代码中,您正在做一个非常低效的事情来复制数据。 CUDA运行时具有功能cudaMemcpy2D,它可以完成您通过在不同行上循环执行的操作。

cudaMallocPitch所做的是计算最佳间距(=二维数组中行间的字节距离),使得每个新行开始于最佳聚合地址,然后分配一个与间距一样大的存储区乘以你指定的行数。您可以在OpenCL中模拟相同的事物,方法是首先计算最佳音调,然后分配正确的大小。

通过以下方式计算最佳音高:(1)获取卡的基地址对齐偏好(CL_DEVICE_MEM_BASE_ADDR_ALIGN属性和clGetDeviceInfo:请注意,返回的值是以位为单位的,所以您必须除以8以字节为单位) ;我们称之为base(2)找到base的最大倍数,它不小于您的自然数据间距(sizeof(type)times列数);这将是你的pitch

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

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

相关问题