pyOpenCL 和 2D FFT

1 投票
1 回答
909 浏览
提问于 2025-04-18 01:02

我正在使用pyFFT对一个二维数组进行傅里叶变换,然后继续进行另一个OpenCL程序(这里以加倍为例):

gpu_data = cl_array.to_device(queue, tData2D)  
plan.execute(gpu_data.data)  
eData2D = gpu_data.get()  


ctx = cl.Context([cl.get_platforms()[0].get_devices()[0]])
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
eData2D_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=eData2D)
eData2D_dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, eData2D.nbytes)
prg = cl.Program(ctx, """
        //#define PYOPENCL_DEFINE_CDOUBLE     // uncomment for double support.
        #include "pyopencl-complex.h"    
        __kernel void sum(const unsigned int ySize,
                              __global cfloat_t *a,
                              __global cfloat_t *b)
        {
          int gid0 = get_global_id(0);
          int gid1 = get_global_id(1);

          b[gid1 + ySize*gid0] = a[gid1 + ySize*gid0]+a[gid1 + ySize*gid0];
        }
        """).build()

prg.sum(queue, eData2D.shape, None, np.int32(Ny), eData2D_buf, eData2D_dest_buf)
cl.enqueue_copy(queue, eData2Dresult, eData2D_dest_buf) 

这个过程运行得非常顺利。现在,我不想再把数据取出来,然后再复制到一个缓冲区 eData2D = gpu_data.get(),再把它复制回GPU内存 eData2D_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=eData2D),我希望能继续使用它。

我本来期待能像这样做:

gpu_data = cl_array.to_device(queue, tData2D)  
plan.execute(gpu_data.data)


ctx = cl.Context([cl.get_platforms()[0].get_devices()[0]])
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
eData2D_dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, eData2D.nbytes)
prg = cl.Program(ctx, """
        //#define PYOPENCL_DEFINE_CDOUBLE     // uncomment for double support.
        #include "pyopencl-complex.h"    
        __kernel void sum(const unsigned int ySize,
                              __global cfloat_t *a,
                              __global cfloat_t *b)
        {
          int gid0 = get_global_id(0);
          int gid1 = get_global_id(1);

          b[gid1 + ySize*gid0] = a[gid1 + ySize*gid0]+a[gid1 + ySize*gid0];
        }
        """).build()

prg.sum(queue, eData2D.shape, None, np.int32(Ny), gpu_data.data, eData2D_dest_buf)
cl.enqueue_copy(queue, eData2Dresult, eData2D_dest_buf) 

但这个方法没有成功。有没有办法做到这一点呢?感谢你的帮助。

1 个回答

1

看起来你是在为第二个程序创建一个全新的环境:

ctx = cl.Context(...)

OpenCL的缓冲区只能在它创建时的那个环境中使用,所以如果你想像这样重复使用缓冲区,就得确保两个OpenCL程序或内核使用的是同一个环境。

你也可以重复使用命令队列,而不是创建一个新的。

撰写回答