使用openCL / C实现矩阵乘法

时间:2012-11-04 00:31:16

标签: c arrays matrix opencl

我理解矩阵乘法的理论,我对这个特定的内核实现只有两个问题:

作为参考,num_rows = 32.矩阵B(b_mat)之前被另一个内核转换,据我所知,我们将行向量点在一起。

1)为什么我们需要使用参数“vectors_per_row”,从而使用内循环?我以为我们可以做sum + = dot(A行,B行),看起来这个param将行分成更小的部分(为什么?)。

2)我不理解a_mat和b_mat的地址偏移,即a_mat + = start; b_mat + = start * 4;

__kernel void matrix_mult(__global float4 *a_mat,
   __global float4 *b_mat, __global float *c_mat) {
   float sum;
   int num_rows = get_global_size(0);
   int vectors_per_row = num_rows/4;
   int start = get_global_id(0) * vectors_per_row;    
   a_mat += start;                                          
   c_mat += start*4;                                  
   for(int i=0; i<num_rows; i++) {             
      sum = 0.0f;                                      
      for(int j=0; j<vectors_per_row; j++) {   
         sum += dot(a_mat[j],                  
                b_mat[i*vectors_per_row + j]); 
      }                                     
      c_mat[i] = sum;                           
   }                                        
}

1 个答案:

答案 0 :(得分:2)

  1. 您的矩阵由一系列float4组成。 Flaoa4是4个浮点数的向量。这就是4来自哪里。 Dot仅适用于内置类型,因此您必须在float4上执行此操作。

  2. c_mat的类型为float,这就是它启动* 4和a_mat启动的原因。偏移是因为代码被分成几个(可能是数百个)线程。每个线程仅计算乘法运算的一小部分。 start只是线程开始计算的地方。这就是get_global_id(0)的用途。它基本上得到你的线程ID。从技术上讲,它是第一个维度的线程索引,但看起来你只有一个线程维度,所以在这里你可以把它想象成线程id。