我想将相同尺寸的数组1xN
减去尺寸为MxN
的矩阵的每一行。即,执行numpy
时执行相同的操作a-b
,前者是矩阵,后者是数组。例如:
import pyopencl as cl
import pyopencl.array as cl_array
import numpy as np
a = np.matrix('1 2 3; 4 5 6').astype(np.float32)
b = np.array([1,2,3]).astype(np.float32)
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
a_dev = cl_array.to_device(queue, a)
b_dev = cl_array.to_device(queue, b)
dest_dev = cl_array.empty_like(a_dev)
prg = cl.Program(ctx, """
__kernel void fun(
const unsigned int size,
__global const float *a,
__global const float *b,
__global float *c)
{
int i = get_global_id(0);
int j = get_global_id(1);
c[i + j*size] = a[i + j*size] - b[j];
}
""").build()
prg.fun(queue, a.shape, None, np.int32(len(a)), a_dev.data, b_dev.data, dest_dev.data)
print(dest_dev)
我认为该内核将返回矩阵
[0 0 0 ; 3 3 3]
但实际上它返回
[0 1 1 ; 2 2 3]
哪里出了错?
答案 0 :(得分:1)
您必须在内核中交换矩阵计算的行和列。您可以使用
a.shape # returns tuple(rows, columns)
返回。它返回(2, 3)
而不是(3, 2)
。因此,更改内核中的行,即可在其中对矩阵进行计算:
c[j + i*size] = a[j + i*size] - b[j];
在这种情况下,i
是行数,j
是列数。
将矩阵的size
赋予内核时,也会出错。代替
np.int32(len(a))
返回2的行数(y轴)。将内核启动行更改为:
prg.fun(queue, a.shape, None, np.int32(a.shape[1]), a_dev.data, b_dev.data, dest_dev.data)
a.shape[1]
为您提供矩阵第二维的大小,即示例中的列数3。
还可以使用Work-Item内置函数查询内核本身中的列数:
unsigned int size = get_global_size(1); // size of the 2. dim of the kernel
在这种情况下,您不必将列数作为内核参数传递。