需要帮助,我正在尝试使用OpenCL在我的GPU上执行矩阵乘法。结果似乎非常错误,但是矩阵的尺寸是正确的。我不确定是否存在一些错误的指针问题。请帮忙。
尝试了int和float(无关紧要),但是都失败了。
import pyopencl as cl
import numpy as np
import numpy.linalg as la
import datetime
import os
os.environ['PYOPENCL_COMPILER_OUTPUT'] = '1'
def openCL_multiplication(matrix1, matrix2):
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
a_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=matrix1)
b_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=matrix2)
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, matrix1.nbytes )
prg = cl.Program(ctx, """
__kernel void multiplymatrices( int size, __global float * matrix1, __global float * matrix2, __global float * res) {
int i = get_global_id(1);
int j = get_global_id(0);
res[i + size * j] = 0;
for (int k = 0; k < size; k++)
{
res[i + size * j] += matrix1[k + size * i] * matrix2[j + size * k];
}
}
""").build()
t0 = datetime.datetime.now()
print("Size:" + str(np.int32(len(matrix1))))
print("a:" + str(a_buf))
print("b:" + str(b_buf))
prg.multiplymatrices(queue, matrix1.shape, None,np.int32(len(matrix1)) ,a_buf, b_buf, dest_buf)
final_matrix = np.empty_like(matrix1)
cl.enqueue_copy(queue, final_matrix , dest_buf)
print (final_matrix)
delta_t = datetime.datetime.now() - t0
print ('OpenCL Multiplication: ' + str(delta_t))
return final_matrix
M1 = np.array([[2,3],[1,4]])
M2 = np.array([[1,2],[3,4]])
print(M1)
print(M2)
res = openCL_multiplication(M1, M2)
print(res)
输出如下: OpenCL乘法:0:00:00.004049
[[0 0] [4323174168305532928 4323174168305532928]]
答案 0 :(得分:0)
我真的不了解python或pyopencl,但是您的OpenCL内核代码看起来还可以。 (尽管我将结果累加到一个私有变量中,最后只写一次res[i + size * j]
;这将效率更高,但代码应该提供正确的结果。)
4323174168305532928
是0x3BFF00003BFF0000
,乍一看对我来说就像2个32位浮点数的二进制表示。因此,我怀疑您的内核很好,但是您对缓冲区的处理不正确-您将它们解释为错误的数据类型,64位整数而不是浮点数。这将是pyopencl / python特有的,因此我无法告诉您正确的答案,但是希望这可以使您走上正确的道路,以自己解决问题,或者其他人也可以加入。