【问题标题】:wrong value with pyopencl outputpyopencl 输出的值错误
【发布时间】:2020-05-14 03:28:23
【问题描述】:

我正在编写一个使用 pyOpenCL 的代码,并且在该代码的一部分中,我需要多次将一个数组导入到 openCL 函数(如示例中的 p)和一个该数组的特殊索引必须增加另一个参数(如示例中的 src ,其元素始终为 1 作为示例)。我写了以下代码,但它不能正常工作。

import pyopencl as cl
import numpy as np
import os

os.environ['PYOPENCL_CTX']='0:1'

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

mf=cl.mem_flags

prg=cl.Program(ctx,"""
__kernel void src_injection(__global float *p,int src_i,int src_j, float src)
{
 int nx=get_global_size(1);
 int idx=src_i*nx+src_j;
 p[idx]+=src;

 }
""").build()


nz, nx=50,50

nt=5

p =np.zeros((nz,nx),dtype=np.float32)
p_buff  = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=p)

src=np.ones(nt,dtype=np.float32)        
i=np.int32(2);
j=np.int32(2);             
for k in range(nt):
    prg.src_injection(queue,(nz,nx),None,
               p_buff,i,j,src[k])
    cl.enqueue_copy(queue,p,p_buff)
    print(p[i,j])

如果我将 nxnz 设置为较小的值(例如,两者都为 5),我会以其他方式得到正确的结果,答案似乎不正确.

例如,我正在寻找类似的答案

1.0
2.0
3.0
4.0
5.0

从我的代码,但我得到

2.0
4.0
5.0
6.0
8.0

谁能告诉我,我做错了什么? 谢谢

【问题讨论】:

    标签: python opencl pyopencl


    【解决方案1】:

    我改变了内核如下,它运行良好。顺便说一句,我仍然渴望是否有办法避免在内核中使用 if。所以,如果你对我有小费,请告诉我。谢谢大家!

    prg=cl.Program(ctx,"""
    __kernel void src_injection(__global float *p,int src_i,int src_j, float src)
    {
     int nx=get_global_size(1);
     int i=get_global_id(0);
     int j=get_global_id(1);
    
     if (i==src_i && j==src_j){
             p[i*nx+j]+=src;
             }
    
    
     }
    """).build()
    

    【讨论】:

    • 如果您将 src 更改为浮点数组,您应该能够使用p[i*nx+j]=src[i*nx+j] 一次更新整个矩阵。这样您就可以删除if 语句。在主机(python)端,您需要将所有 src 值放入一个数组并将其加载到一个 opencl 缓冲区中。您的原始实现似乎遍历主机端的索引,然后对内核函数进行多次调用。这是 opencl 中的反模式。您应该将您的程序设计为在一次内核调用中执行所有src_injection 任务。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多