CSCMM для разреженных плотных умножений Armadillo

Среда : armadillo 4.320.0 и 4.400
Компилятор : Компилятор Intel CPP
ОС : Ubuntu 12.04

Я пытаюсь заменить собственное разреженное плотное умножение Armadillo на вызов CSCMM Intel MKL. Я написал следующий код.

#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 показывает некоторые ошибки памяти.

Дайте мне знать, как сделать вызов Intel MKL, используя матричные структуры данных Armadillo. Особенно разреженное плотное умножение.


person Ramakrishnan Kannan    schedule 16.09.2014    source источник


Ответы (1)


Библиотека Libarmadillo также должна быть связана с mkl_ilp64 вместо mkl_lp64. Следуйте приведенным ниже инструкциям.

Сборка и установка броненосца:

  • экспорт CXX=icpc
  • экспорт CC=icpc
  • экспорт PATH=$PATH:/home/ramki/intel/bin:
  • Отредактируйте $armadillo_root/cmake_aux/Modules/ARMA_FindMKL.cmake, правильно укажите ПУТИ.
  • Отредактируйте $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) измените CMAKE_CXX_FLAGS, как указано intel Link Advisor.
  • Запустите ./configure и убедитесь, что для blas и lapack используется библиотека MKL, icpc — компилятор, а все остальное в порядке.
  • Беги сделай.
  • Проверьте связанные библиотеки, запустив ldd libarmadillo.so. В основном проверьте, связан ли он с библиотекой mkl_ilp64 и библиотеками mkl blas и lapack.
  • Теперь запустите make install DESTDIR=local path.

В программе C++

  • Не вводите регистр const ptr A.values ​​в ptr A.values, используя функцию const_cast. Он искажает указатель и не уверен, что мы передаем правильный указатель в cscmm. Вместо этого дублируйте только значения A в отдельном массиве.
  • Убедитесь, что вы устанавливаете правильные ldb и ldc.
  • pntrb и pntre могут быть A.col_ptrs и A.col_ptrs+1.
  • Используйте MKL_INT вместо long long.

Надеюсь, это поможет всем.

person Ramakrishnan Kannan    schedule 24.09.2014