如何从 PyOpenCL 中矩阵的每一行中减去一个数组?

How to subtract an array from each row in matrix in PyOpenCL?

我想将相同的维度数组 1xN 减去维度矩阵 MxN 的每一行。即numpya-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)

我认为这个内核会 return 矩阵

[0 0 0 ; 3 3 3]

但实际上 returns

[0 1 1 ; 2 2 3]

哪里错了?

您必须在内核中交换矩阵计算的行和列。您以

的维度启动内核
a.shape           # returns tuple(rows, columns)

returns。它 returns (2, 3) 而不是 (3, 2)。因此,将内核中计算矩阵的行更改为:

c[j + i*size] = a[j + i*size] - b[j];

在这种情况下,i 是行数,j 是列数。

把矩阵的size给kernel的时候也有错误。而不是

 np.int32(len(a)) 

whitch returns 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

在这种情况下,您不必将列数作为内核参数传递。