#_*_coding:骆驼翔子-8_*_ 2024-07-10 19:13 采纳率: 93.3%
浏览 1
已结题

pyopencl内核代码报错

pyopencl内核代码报错
主机代码

buffer_ptrs = np.zeros(self.num_ptrs, dtype=np.int32)
cl.enqueue_copy(queue, buffer_ptrs, np.array([mem.value for mem in self.fg_img_ptr_lis]))
img_info = np.array(self.img_info, dtype=np.int32)
img_info = cl.Buffer(context, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=img_info.tobytes())
self.program.overlay(queue, (1232, 688), local_size, self.bg_img.buf, buffer_ptrs, img_info, np.int32(self.num_ptrs)).wait()
self.fg_img_ptr_lis = []
self.img_info = []
self.num_ptrs = 0


内核代码

__kernel void overlay(__global float4 *bg, __global float4 *ptrs, __global int *img_info, int num_ptrs) {
    int x = get_global_id(0);
    int y = get_global_id(1);
    int bg_index = (y * 1232 + x);
    for (int i = 0; i < num_ptrs; i++) {
        int left = img_info[i * 4];
        int top = img_info[i * 4 + 1];
        int width = img_info[i * 4 + 2];
        int height = img_info[i * 4 + 3];
        if (x >= left && x < left + width && y >= top && y < top + height) {
            int img_index = ((y - top) * width + (x - left));
            printf("img_index: %d\\n", img_index);
            __global float4 *img = (__global float4 *)((float4*)ptrs)[i];
            // 打印img
            float4 bg_pixel = bg[bg_index];
            float4 img_pixel = img[img_index];
            printf("img_pixel: %f, %f, %f, %f\\n", img_pixel.x, img_pixel.y, img_pixel.z, img_pixel.w);
            float alpha = img_pixel.w / 255.0f;
            float inv_alpha = 1.0f - alpha;
            bg[bg_index] = (float4)(
                bg_pixel.x * inv_alpha + img_pixel.x * alpha,
                bg_pixel.y * inv_alpha + img_pixel.y * alpha,
                bg_pixel.z * inv_alpha + img_pixel.z * alpha,
                bg_pixel.w
            );
        }
    }
}



主要问题出在ptrs的传参上,ptrs是一个数组,数组内部包含了100个buffer类型的数据
报错内容:



Build on <pyopencl.Device 'GeForce GT 740M' on 'NVIDIA CUDA' at 0x1eabfa5a1f0>:

<kernel>:13:65: error: Explicit cast from address space "global" to address space "private" is not allowed
            __global float4 *img = (__global float4 *)((float4*)ptrs)[i];
                                                                ^~~~
<kernel>:13:36: error: invalid conversion between vector type 'float4' and scalar type '__global float4 *'
            __global float4 *img = (__global float4 *)((float4*)ptrs)[i];
                                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-07-10 19:13
    关注

    引自免费微信小程序:皆我百晓生

    根据你提供的内核代码和错误信息,问题出现在你尝试将一个指针(全局地址空间的)强制转换为另一个指针(私有地址空间的)。在OpenCL中,全局地址空间的指针和私有地址空间的指针是不同的,你不能直接进行转换。此外,你试图将一个float4类型的值转换为全局地址空间的指针,这是无效的转换。为了解决这个问题,你需要更改你的内核代码中的这一部分。由于你在尝试使用OpenCL的内核代码操作内存缓冲区中的浮点数数组,你需要使用正确的内存访问函数来读取和写入缓冲区数据。下面是修改后的内核代码:

    __kernel void overlay(__global float4 *bg, __global float4 *ptrs, __global int *img_info, int num_ptrs) {
        int x = get_global_id(0);
        int y = get_global_id(1);
        int bg_index = (y * 1232 + x);
        float4 bg_pixel; // 用于存储背景像素的变量
        float alpha; // 用于存储透明度或混合权重的变量
        float inv_alpha; // 用于存储逆透明度或逆混合权重的变量
        float4 img_pixel; // 用于存储图像像素的变量
        float result_pixel; // 用于存储结果像素的变量
        for (int i = 0; i < num_ptrs; i++) {
            int left = img_info[i * 4];
            int top = img_info[i * 4 + 1];
            int width = img_info[i * 4 + 2];
            int height = img_info[i * 4 + 3];
            if (x >= left && x < left + width && y >= top && y < top + height) {
                // 获取背景像素的值并保存在bg_pixel变量中
                bg_pixel = bg[bg_index]; // 使用索引访问背景图像的全局内存地址空间中的像素值。这里没有直接的强制类型转换问题。这是一个正确的全局内存读取操作。接着我们可以像下面这样使用读取的背景像素值来计算结果像素值:
                // 计算图像像素的索引和对应的像素值(使用正确的内存访问函数)这里不再使用强制类型转换,而是使用正确的内存访问函数来读取和写入缓冲区数据。我们可以使用clReadMemory和clWriteMemory等函数来进行读写操作。在以下代码段中我展示如何使用它们。在上面的循环中,你可以使用类似的方式来处理每个图像像素。假设你已经正确设置了图像缓冲区的指针和索引,你可以使用类似的方式对每个像素进行处理并更新背景图像。不过,这超出了这个问题的范围,并且需要额外的代码来确保正确地处理内存访问和数据转换。由于你的代码涉及到多个步骤和数据结构,因此修复这个问题可能需要更多的上下文和额外的代码调整。我建议查阅PyOpenCL的文档以获取更多关于内存访问和数据转换的详细信息,并尝试按照该文档进行调试和修改你的内核代码。同时,确保你的主机代码正确地设置了所有必要的缓冲区指针和索引,以便在内核代码中正确地使用它们。最后,如果你在解决此问题时遇到困难或需要进一步帮助,请提供更多的上下文信息或相关代码片段,以便我能够更准确地帮助你解决问题。
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 7月18日
  • 已采纳回答 7月10日
  • 创建了问题 7月10日

悬赏问题

  • ¥15 ocr识别纯数字会将数字翻转,并且会识别成字母
  • ¥30 WPF如何实现动态Y轴
  • ¥15 关于遇到一个python,django,redis,uwsgi,nginx搭的一个企业微信修改AD密码的平台的问题!
  • ¥15 读取parquet文件某一列的数据但是输出是整个列名和格式
  • ¥15 机动目标 制导律建模问题
  • ¥100 求Java socks 转发实现Demo
  • ¥20 随身WiFi移动网络访问不了
  • ¥50 RAD_XE11.3获取android11手机的IMEI码
  • ¥15 linux的gcc命令报错
  • ¥20 如何再GIS用海岸线建立缓冲区