Pyopencl write_imagef函数似乎没有改变image2d_t对象

时间:2014-01-05 00:46:19

标签: python opencl pyopencl

我一直在努力学习OpenCL并偶然发现了一些问题。在下面的代码中,我创建一个空的write_only opencl图像对象,并尝试将一个简单的内核变为黑色(或至少以某种方式更改它),但它只返回一个空图像。 (我正在进行图像卷积练习,它不断返回一个空图像,下面的代码只是试图找出问题。)

我现在已经乱了2个多小时了,我很确定我被卡住了。

import matplotlib.pyplot as plt
import scipy.ndimage as si
import pyopencl as cl
import numpy as np
import os

kernel = """
__kernel void black(__write_only image2d_t dst,
                    int rows,
                    int columns)
{
    const int column = get_global_id(0);
    const int row = get_global_id(1);

        if (column < columns && row < rows)
        {
            write_imagef(dst, (int2)(column, row),
                (float4)(1.0f, 1.0f, 1.0f, 1.0f));
        }   
}
"""

ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)

mf = cl.mem_flags

f = cl.ImageFormat(cl.channel_order.R, cl.channel_type.UNSIGNED_INT8)

dst_image = cl.Image(ctx, mf.WRITE_ONLY , f, shape=(100,100,4))

prg = cl.Program(ctx, kernel).build()

prg.black(queue, (100,100), None, dst_image,
          np.int32(100),
          np.int32(100))

postimage = np.zeros((100,100,4), dtype=np.uint8)
cl.enqueue_copy(queue, postimage, dst_image,
                origin=(0, 0, 0),
                region=(100,100,4))

plt.imshow(postimage)
plt.show()

1 个答案:

答案 0 :(得分:1)

你的内核代码实际上很好(尽管你发布的代码将每个像素设置为白色,因此很难判断它是否正常工作!)。问题在于您创建图像的方式。在shape=(100,100,4)构造函数中指定cl.Image时,实际上是在要求3D图像。

让示例代码生成有用的东西的最简单方法是修改这些行:

f = cl.ImageFormat(cl.channel_order.R, cl.channel_type.UNSIGNED_INT8)
....
dst_image = cl.Image(ctx, mf.WRITE_ONLY , f, shape=(100,100,4))
...
cl.enqueue_copy(queue, postimage, dst_image,
                origin=(0, 0, 0),
                region=(100,100,4))

f = cl.ImageFormat(cl.channel_order.RGBA, cl.channel_type.UNSIGNED_INT8)
....
dst_image = cl.Image(ctx, mf.WRITE_ONLY , f, shape=(100,100))
....
cl.enqueue_copy(queue, postimage, dst_image,
                origin=(0, 0),
                region=(100,100))

在这里,我已经将图像格式更改为RGBA,它与matplotlib图像显示功能所期望的相匹配(我不熟悉该库,因此您可以将其显示出来单通道图像也是如此)。我还修改了创建图像的线条,并将其复制回主机,而不是3D。

现在,如果您更改内核以将此数据写入图像:

write_imagef(dst, (int2)(column, row), (float4)(1.0f, 0.0f, 0.0f, 1.0f));

你应该得到一个漂亮的红色输出图像!