大型矩阵上的cblas_dgemm分段错误

时间:2014-08-21 13:41:05

标签: c++ c blas intel-mkl

我正在开发一台24核的机器,内存大约400GB,运行Ubuntu。使用英特尔MKL cblas_dgemm:

进行简单的矩阵乘法时遇到分段错误
  int k=5;
  int m=2E5;
  int n=3E4;
  double * A = (double *)mkl_malloc( m*k*sizeof( double ), 64 );
  UTILITIES::check_alloc("A", A); //Check alloc just checks if the pointer is null
  UTILITIES::random_matrix(m,k,A); //fills matrix with random numbers

  double * B = (double *)mkl_malloc( k*n*sizeof( double ), 64 );
  UTILITIES::check_alloc("B", B);
  UTILITIES::random_matrix(k,n,B); //files matrix with random numbers

  double * TestMatrix = (double *)mkl_malloc( m*n*sizeof( double ), 64 );
  printf("Allocating a matrix of size %le\n",(double) m*n*sizeof(double)); //4.8E10
  UTILITIES::check_alloc("TestMatrix", TestMatrix);//No problem

  for (int i=0; i<m*n; i++) { //I added this just to make sure I could allocate the memory, of course this will all be overwritten
    TestMatrix[i] = 1.0;
  }

  printf("TestMatrix %lf\n", TestMatrix[1]); //no problem accessing the memory

  cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m,n,k,
      1.0,
      A,k,
      B,n,
      0.0,
      TestMatrix,n); //Segfaults at this line (without it, there is no segfault).

如果我改变矩阵的大小,使n = 1E4,则没有分段错误。

你有什么想法吗?

请注意,我已确认我正在使用64位进行编译:

#if __x86_64__
  printf("Running 64 bit\n");
#endif

我的编译行:

g++ -m64 main.cpp -I/opt/intel/composer_xe_2013_sp1.0.080/mkl/include -L/opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64 -lmkl_rt;

2 个答案:

答案 0 :(得分:3)

我的最佳猜测是m*n初始化for循环导致溢出。

然而,(归功于mch)段错误是由于m*n*sizeof(double)中的溢出造成的。显然m*n会在上传到size_t之前进行评估。解决此问题的一种方法是将mn更改为long long,并相应地i

答案 1 :(得分:1)

  cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m,n,k,
      1.0,
      A,k,
      B,n,
      0.0,
      TestMatrix,n);

----------------------------- ^尝试更改为m

From the documentation,最后一个参数:

  

LDC

     

基质C的第一维尺寸;如果你要通过   矩阵C [m] [n],该值应为m。