opencl:clEnqueueNDRangeKernel执行报错CL_OUT_OF_RESOURCES的一种情况

我的电脑上之前的显卡比较老并不支持opencl,所以我之前开发时opencl代码其实都是在CPU上跑的,现在所有的代码都调试通过了,决定装块新显卡用于程序的性能测试。
今天显卡到了,装上之后运行程序,clEnqueueNDRangeKernel在执行下面的kernel时报错:CL_OUT_OF_RESOURCES

__kernel void prefix_sum_col_and_transpose( __constant SRC_TYPE *src, __global DST_TYPE * dst, uint width,uint height, uint src_width_step, uint dst_width_step){
	.........// 代码实现部分略过
}

百撕不得其姐啊。。。。这代码在CPU上跑很正常,逻辑没问题呀。
最后发现只是kernel 指针参数的地址修饰符使用不当造成的。

上面这段代码,是用于图像积分图计算的,对给定的原图(src)数据计算积分图,输出到目标指针(dst)指向的全局内存中。因为src数据不允许被修改所以我想当然的把src指定为__constant
而这里用__constant修饰是不对的。__constant__global都是全局内存,__constant修饰的地址指向的是常量,不能被修改,但它们之间的区别却并不仅于此。
一个opencl设备的常量空间是有限制的,通过clGetDeviceInfo获取CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE可以知道一个opencl设备的最大常量缓冲区的尺寸,在我的显卡上,这个值是65536,简单通过命令行运行AMD APP SDK的clinfo就可以得到这个值,如下图:
这里写图片描述

因为图像的尺寸很容易就超过64kb,所以clEnqueueNDRangeKernel在执行kernel时无法将它放到opencl设备的constant buffer中,所以就会报错CL_OUT_OF_RESOURCES
所以应该将src的地址修饰符从__constant改为__global,如果要禁止修改src指针的数据,前面用c语言标准的const关键字修饰这个指针就可以了,所以这个kernel函数正确的定义应该是这样:

__kernel void prefix_sum_col_and_transpose( const __global SRC_TYPE *src, __global DST_TYPE * dst, uint width,uint height, uint src_width_step, uint dst_width_step){
	.........// 代码实现部分略过
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值