利用Opencl加速Eigen的矩阵运算(一)

很多时候OpenCL启用GPU加速大规模矩阵运算可以达到减少计算时间的目的。但是目前一般成熟代码里面的矩阵运算不会是简单的float数组或者double数组,而是通过特定的结构体进行计算。其中Eigen就是专门针对矩阵计算的库,里面涉及到大量的矩阵操作。那么如何用OpenCL对Eigen进行加速呢?

简单来看就是将Eigen的矩阵结构体声明放到OpenCL的核函数中,但是本人技术浅薄,无法实现这一步。因为虽然OpenCL的核函数支持引入外部库,但是之前没弄通,所以这块还没有实验。

我主要实现的方法是先将Eigen声明的矩阵拷贝到准备好的double数组中,然后将double数组传入kernel中进行矩阵运算。

方法一:使用指针指向Eigen矩阵
对Eigen矩阵拷贝中如果直接使用指针的话,指针得到的数据是按列读的。因为指针指向的是连续地址块,而矩阵的地址是按列增加的。

这样的好处是不需要再声明内存和数据copy,可以直接使用矩阵的内存。

缺陷是当取block的时候,由于地址连续不能取到块。比如下面的例子中,在3x3的矩阵中从(1,1)处开始取个2x2的矩阵,应该得到(1,1),(2,1),(1,2),(2,2)这四处数据。但是实际上如果令指针指向(1,1),空间大小声明为
4*sizeof(double),指针指向的值是(1,1),(1,2),(2,0),(2,1)。大家可以实验验证。

方法如下:

  Matrix3d eigMat;
  eigMat << 5, 2, 3, 4, 5, 6, 7, 8, 9;
 
  double* mf = eigMat.data();
  cout << eigMat << endl;
  for (int j = 0; j < eigMat.size(); j++)
   cout << mf[j]<<" ";
  for (int j = 0; j < eigMat.size(); j++)
   mf[j] = j + 1;
  cout << endl;
  cout << "this is update" << endl;
  cout << eigMat << endl;

运行结果如下:
指针按列读取
方法二:使用Eigen的Map进行数据copy

自己先声明一定空间的内存,比如double数组,然后将Eigen的矩阵copy过来。此时可以通过参数ColMajor和RowMajor选择是按列还是按行copy。这样的好处是可以对矩阵取block的时候进行完整取到。但是在用kernel计算完数组,从数组copy回矩阵时,只能按照列填充(这块要注意)。
代码如下:

Matrix<double, 8, 8> eigMatA;
for (int i = 0; i < 8; i++)
 {
  for (int j = 0; j < 8; j++)
  {
  	eigMatA(i, j) = i * j+1;
  }
 }
 double* pA = (double*)malloc(sizeof(double) * eigMatA.size());
 Map<Matrix<double, 8, 8>, RowMajor>(pA , eigMatA.rows(), eigMatA.cols()) = eigMatA;//将矩阵copy到数组,按行
 // Map<Matrix<double, 8, 8>, ColMajor>(pA , eigMatA.rows(), eigMatA.cols()) = eigMatA;//将矩阵copy到数组,按列
 //中间可以自行对数组进行操作
 
 eigMatA = Map<Matrix<double, 8, 8>, RowMajor>(pA , eigMatC1.rows(), eigMatC1.cols());//将数据copy到矩阵,按列

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水流water

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值