Python Pyopencl write_imagef函数似乎不会更改image2d_t对象
我一直在尝试学习OpenCL,但遇到了一个小问题。在下面的代码中,我创建了一个空的只写opencl图像对象,并尝试让一个简单的内核变为黑色(或者至少以某种方式更改它),但是它只返回一个空图像。(我正在做一个图像卷积练习,它不断返回一个空图像,下面的代码只是试图隔离问题。) 我已经胡闹了两个多小时了,我很确定我被卡住了Python Pyopencl write_imagef函数似乎不会更改image2d_t对象,python,opencl,pyopencl,Python,Opencl,Pyopencl,我一直在尝试学习OpenCL,但遇到了一个小问题。在下面的代码中,我创建了一个空的只写opencl图像对象,并尝试让一个简单的内核变为黑色(或者至少以某种方式更改它),但是它只返回一个空图像。(我正在做一个图像卷积练习,它不断返回一个空图像,下面的代码只是试图隔离问题。) 我已经胡闹了两个多小时了,我很确定我被卡住了 import matplotlib.pyplot as plt import scipy.ndimage as si import pyopencl as cl import nu
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()
导入matplotlib.pyplot作为plt
将scipy.ndimage导入为si
将pyopencl作为cl导入
将numpy作为np导入
导入操作系统
kernel=”“”
__内核无效黑色(uuu只写图像2D_ut dst,
int行,
int列)
{
const int column=get_global_id(0);
const int row=get_global_id(1);
if(列<列和行<行)
{
写入图像F(dst,(int2)(列,行),
(浮动4)(1.0f、1.0f、1.0f、1.0f));
}
}
"""
ctx=cl.创建一些上下文()
queue=cl.CommandQueue(ctx)
mf=cl.mem_标志
f=cl.ImageFormat(cl.channel\u order.R,cl.channel\u type.UNSIGNED\u INT8)
dst_image=cl.image(仅限ctx、mf.WRITE_、f、shape=(100100,4))
prg=cl.Program(ctx,kernel.build())
prg.黑色(队列,(100100),无,dst_图像,
np.int32(100),
np.int32(100))
postimage=np.Zero((100100,4),dtype=np.uint8)
cl.enqueue_副本(队列、后期图像、dst_图像、,
原点=(0,0,0),
地区=(100100,4))
plt.imshow(后期图像)
plt.show()
您的内核代码实际上很好(尽管您发布的代码将每个像素设置为白色,因此很难判断它是否工作!)。问题在于您创建图像的方式。当您在cl.Image
构造函数中指定shape=(100100,4)
时,实际上您要求的是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))
到
在这里,我将图像格式更改为RGBA,这与matplotlib
图像显示函数所期望的内容相匹配(我不熟悉该库,因此可能您也可以让它显示单通道图像)。我还修改了创建图像并将其复制回宿主的线条,使其为2D,而不是3D
现在,如果更改内核以将此数据写入映像:
write_imagef(dst, (int2)(column, row), (float4)(1.0f, 0.0f, 0.0f, 1.0f));
你应该得到一个漂亮的红色输出图像 该规范规定“write_imageui只能用于使用设置为以下值之一的image_channel_data_type创建的图像对象:CL_UNSIGNED_INT8、CL_UNSIGNED_INT16或CL_UNSIGNED_INT32。”。我在列表中没有看到
CL\u UNORM\u INT8
。试着用write\u imagef
也许吧。我试过write\u imagef和write\u imagei,都没用。
write_imagef(dst, (int2)(column, row), (float4)(1.0f, 0.0f, 0.0f, 1.0f));