PyOpencl - 错误的参数传递给kernell

时间:2014-12-29 16:57:31

标签: python parallel-processing pyopencl

我很难用PyOpenCl进行基本的标量操作 基本上,我想要做的是,给定一个浮点型数组,将每个数组元素乘以标量浮点数并将结果放在一个新的缓冲区上。这应该很容易,但由于某种原因,它并没有像它应该的那样萎缩。

这是我正在使用的代码:(带有_h的变量是HOST变量;带有_g的变量是设备变量)

import numpy as np
import pyopencl as cl
# Device Init
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
MF = cl.mem_flags

# Host Initial Variables
a_h = np.array([1.0, 2.0, 3.0, 4.0])
b_h = np.float32(2.0)

# DEVICE Variable Allocation
a_g = cl.Buffer(ctx, MF.READ_ONLY | MF.COPY_HOST_PTR, hostbuf=a_h)
c_g = cl.Buffer(ctx, MF.WRITE_ONLY, a_h.nbytes)

# DEVICE's Kernel - Multiply each element of the array a_g by the scalar b_g and put the result on the array c_g
source = """
__kernel void mult(float b_g, __global float *a_g, __global float *c_g){
    const int gid = get_global_id(0);
    c_g[gid] = b_g * a_g[gid];
}
"""

prg = cl.Program(ctx, source).build()
prg.mult(queue, a_h.shape, None, b_h, a_g, c_g)

# Export The Result On The DEVICE Back To The HOST
c_h = np.empty_like(a_h)
cl.enqueue_copy(queue, c_h, c_g)

# Output
print c_h

预期的输出是

[2.0 4.0 6.0 8.0]

这是输出:

[  2.56000000e+002   5.12000000e+002  -1.73777009e+308  -1.73777009e+308]

我不明白为什么。我已经尝试过阅读PyOpenCL项目页面,但实际上我并不是很了解它。 我想我没有正确地执行内核部分或内核调用部分。

我尝试过使用内核:

__kernel void mult(__global float *b_g, __global float *a_g, __global float *c_g)

但是正如预期的那样它没有用,因为我没有为b_g创建指针,也不知道如何创建一个指针。错误是:

:2:39: error: parameter may not be qualified with an address space
__kernel void mult(__global float b_g, __global float *a_g, __global float *c_g){
                                  ^

我背后的主要想法很简单:因为我将把这个值b_g用作所有工作者的常用东西,我想把它们放在全局内存上一次,这样每个工作者都可以访问它而不是重复每个工人的价值。

我相信这应该非常简单,但我是并行计算的新手,并且不知道如何解决这个问题。

谢谢。

1 个答案:

答案 0 :(得分:0)

在numpy中,同一数组中包含的所有对象都具有公共数据类型。此数据类型在数组的属性dtype中指定。 (numpy.array docnumpy datatypes

数组a_h中的数据类型为float64(64位浮点数)。由于您的内核需要32位浮点数(float32),因此它会像这样解释a_h的数据。所以它会看到8个32位浮点数而不是4个64位浮点数。

要使其工作,请将a_h中的对象存储为float32。因此,将其定义如下:

a_h = np.array([[1.0, 2.0, 3.0, 4.0], dtype=np.float32)
相关问题