CSMM for Armadillo稀疏密集乘法

时间:2014-09-16 02:21:50

标签: armadillo intel-mkl

环境:犰狳4.320.0和4.400
编译器:英特尔CPP编译器
操作系统:Ubuntu 12.04

我正在尝试用英特尔MKL的CSCMM调用替换Armadillo的原生稀疏密集乘法。我写了下面的代码。

#include <mkl.h>  
#define ARMA_64BIT_WORD
#include <armadillo>

using namespace std;
using namespace arma;

int  main(int argc, char *argv[])
{
   long long m = atoi(argv[1]);
   long long k = atoi(argv[2]);
   long long n = atoi(argv[3]);
   float density = 0.3;
   sp_fmat A = sprandn<sp_fmat>(m,k,density);
   fmat B = randu<fmat>(k,n);
   fmat C(m,n);
   C.zeros();
 //C = alpha * A * B + beta * C;
 //mkl_scscmm (char *transa, MKL_INT *m, MKL_INT *n, MKL_INT *k, float *alpha, char *matdescra,       
 //float *val, MKL_INT *indx, MKL_INT *pntrb, MKL_INT *pntre, float *b, MKL_INT *ldb, float *beta, 
//float *c, MKL_INT *ldc);
  char transa = 'N';
  float alpha = 1.0;
  float beta = 0.0;
  char* matdescra = "GUUC";
  long long ldb = k;
  long long ldc = m;
  cout << "b4 Input A:" << endl << A;
  cout << "b4 Input B:" << endl << B;
  mkl_scscmm (&transa,&m,&n,&k,&alpha,matdescra,
              const_cast<float *>(A.values), (long long *)A.row_indices,
             (long long *)A.col_ptrs,(long long *)(A.col_ptrs + 1),
             B.memptr(),&ldb,
             &beta, C, &ldc);
  cout << "Input A:" << endl << A;
  cout << "Input B:" << endl << B;
  cout << "Input C:" << endl << C;
  return 0;
}

我编译了上面的代码并将其作为“./testcscmm 10 4 6”运行。我收到了分段错误(核心转储)。

[矩阵大小:10x4; n_nonzero:12;密度:30.00%]

 (0, 0)         1.1123
 (4, 0)        -0.3453
 (8, 0)         0.6081
 (1, 1)         0.6410
 (4, 1)        -0.7121
 (5, 1)         1.1592
 (9, 1)        -1.7189
 (0, 2)         0.4175
 (2, 2)        -0.4001
 (4, 2)         2.2809
 (4, 3)        -2.2717
 (9, 3)         0.2251

b4 Input B:
0.1567   0.9989   0.6126   0.4936   0.5267   0.2833
0.4009   0.2183   0.2960   0.9728   0.7699   0.3525
0.1298   0.5129   0.6376   0.2925   0.4002   0.8077
0.1088   0.8391   0.5243   0.7714   0.8915   0.9190
Input A:
[matrix size: 13715672716573367337x13744746204899078486; n_nonzero: 12; density: 0.00%]

Segmentation fault (core dumped)

由于某种原因,A的结构被破坏了。我有以下问题。

  1. MKL_CSCMM会修改输入数组吗?如果不是为什么A会被破坏?
  2. 我将矩阵C更改为本机浮点数。仍然存在错误。
  3. Valgrind显示一些内存错误。
  4. 让我知道如何使用Armadillo的矩阵数据结构进行英特尔MKL调用。特别是稀疏密集乘法。

1 个答案:

答案 0 :(得分:3)

Libarmadillo库也必须与mkl_ilp64而不是mkl_lp64链接。请按照以下说明操作。

建立并安装犰狳:

  • 导出CXX = icpc
  • export CC = icpc
  • export PATH = $ PATH:/ home / ramki / intel / bin:
  • 编辑$ armadillo_root / cmake_aux / Modules / ARMA_FindMKL.cmake,正确包含PATHS。
  • 编辑$ armadillo_root / cmake_aux / Modules / ARMA_FindMKL.cmake,将mkl_lp64更改为mkl_ilp64
  • 编辑$ armadillo_root / CMakeLists.txt和(1)更改CMAKE_SHARED_LINKER_FLAGS以包含intel link advisor的链接行和(2)更改由intel link advisor提供的CMAKE_CXX_FLAGS
  • 运行./configure并确保MKL库用于blas和lapack,icpc用作编译器,剩下的就好了。
  • 运行make。
  • 通过运行ldd libarmadillo.so验证链接的库。主要验证它是否与mkl_ilp64库和mkl blas和lapack库链接。
  • 现在运行make install DESTDIR = local path。

在C ++程序中

  • 不要使用const_cast函数键入A.values的const ptr到ptr A.values。它扭曲指针并且不确定我们是否将右指针传递给cscmm。而是仅在单独的数组中复制A的值。
  • 确保您正在设置正确的ldb和ldc。
  • pntrb和pntre可能是A.col_ptrs和A.col_ptrs + 1.
  • 在长长的地方使用MKL_INT。

希望这有助于每个人。