我希望每个人都熟悉将两个(n x n
平方为简单)矩阵相乘的标准“天真”方法。在C
中,这是:
for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
for(int k = 0; k < n; ++k)
C[i*n + j] += A[i*n + k] * B[k*n + j];
上述方法计算A
行的一个点(内部)乘积,其列为B
,并且易于在OpenCL中实现,如下所示:
__kernel void matmul_ocl(
__global const float *A,
__global const float *B,
__global float *C,
const int n
)
{
const int row = get_global_id(1); // row
const int col = get_global_id(0); // col
for(int i = 0; i < n; i++)
C[row*n + col] += A[row*n + i]*B[i*n + col];
}
交换原始C
实现的两个最内层循环会产生一个计算外部产品的方法,即它计算{{行}的排名-1更新1}}矩阵:
C
有人知道如何在OpenCL中正确实现上述外部产品方法吗?我在下面粘贴了两次尝试,但我似乎无法指出它
尝试1
for(int i = 0; i < n; ++i)
for(int k = 0; k < n; ++k)
for(int j = 0; j < n; ++j)
C[i*n + j] += A[i*n + k] * B[k*n + j];
尝试2
__kernel void matmul_ocl(
__global const float *A,
__global const float *B,
__global float *C,
const int n
)
{
const int row = get_global_id(1); // row
const int col = get_global_id(0); // col
__local float r;
r = A[row*n + col];
barrier(CLK_LOCAL_MEM_FENCE);
for(int i = 0; i < n; ++i)
C[row*n + i] += r * B[col*n + i];
}
答案 0 :(得分:1)
通用算法的OpenCL实现将外部两个循环映射到OpenCL NDRange隐式循环。这是有效的,因为外部的两个循环可以安全地并行运行。
尝试1有一些问题:
围绕第二个问题没有一个简单的方法。 k上的循环(在转置版本中)不能并行运行。您只能将外循环或内循环映射到OpenCL中的单维NDRange。