我一直在努力学习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()
答案 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));
你应该得到一个漂亮的红色输出图像!