在 C Mex-File 中使用 BLAS 库

Posted

技术标签:

【中文标题】在 C Mex-File 中使用 BLAS 库【英文标题】:Use BLAS library in C Mex-File 【发布时间】:2015-11-17 14:22:30 【问题描述】:

我正在尝试为我的 C-Mex-Code 使用 BLAS 库来分析使用和不使用 BLAS 的性能差异。但是,我无法弄清楚如何正确使用 BLAS 而不会出现编译错误/警告(最终导致 Matlab 崩溃)。

下面是一个示例代码,我想使用 Blas 的 ddot() 函数 (https://software.intel.com/de-de/node/468398#D4E53C70-D8FA-4095-A800-4203CAFE64FE) 计算向量积:

  #include <mex.h>
  #include <math.h>
  #include <blas.h>

  void TestBlas(double *L, double *R, mwSize n)
  

      int one = 1;
      double sum = ddot(&n,L,&one,L,&one);

      //Output Matrix R not defined, just for test purposes...

   

  void mexFunction( int nlhs, mxArray *plhs[],
                    int nrhs, const mxArray *prhs[])
  
      double *inMatrix;               /* 1xN input matrix */
      size_t ncols;                   /* size of matrix */
      long *ncolsPr;                  /* output matrix */
      double *outMatrix;              /* output matrix */

      inMatrix = mxGetPr(prhs[0]);
      ncols = mxGetN(prhs[0]);

      /* create the output matrix */
      plhs[0] = mxCreateDoubleMatrix(1,(mwSize)ncols,mxREAL);
      outMatrix = mxGetPr(plhs[0]);

      TestBlas(inMatrix,outMatrix,(mwSize)ncols);
  

我收到的编译器警告是:

 >> mex -largeArrayDims TestBlas.c -lmwblas
  Building with 'Xcode with Clang'.
  /Users/jhess/Dropbox/Uni/E-Technik Master/Forschungspraxis Machine Learning/Matlab/TestBlas.c:9:23: warning: passing 'mwSize *' (aka 'unsigned long *') to parameter of type 'const ptrdiff_t *' (aka 'const long *') converts between pointers to integer types with different sign [-Wpointer-sign]
      double sum = ddot(&n,L,&one,L,&one);
                        ^~
  /Applications/MATLAB_R2015a.app/extern/include/blas.h:559:22: note: passing argument to parameter 'n' here
      const ptrdiff_t *n,
                       ^
  /Users/jhess/Dropbox/Uni/E-Technik Master/Forschungspraxis Machine Learning/Matlab/TestBlas.c:9:28: warning: incompatible pointer types passing 'int *' to parameter of type 'const ptrdiff_t *' (aka 'const long *') [-Wincompatible-pointer-types]
      double sum = ddot(&n,L,&one,L,&one);
                             ^~~~
  /Applications/MATLAB_R2015a.app/extern/include/blas.h:561:22: note: passing argument to parameter 'incx' here
      const ptrdiff_t *incx,
                       ^
  /Users/jhess/Dropbox/Uni/E-Technik Master/Forschungspraxis Machine Learning/Matlab/TestBlas.c:9:35: warning: incompatible pointer types passing 'int *' to parameter of type 'const ptrdiff_t *' (aka 'const long *') [-Wincompatible-pointer-types]
      double sum = ddot(&n,L,&one,L,&one);
                                    ^~~~
  /Applications/MATLAB_R2015a.app/extern/include/blas.h:563:22: note: passing argument to parameter 'incy' here
      const ptrdiff_t *incy
                       ^
  3 warnings generated.

  MEX completed successfully.

这似乎是我将错误的变量类型(或指针类型?)传递给 BLAS 函数,但我不知道如何解决它。有人可以看看吗? 非常感谢!

【问题讨论】:

正如警告所说:ddot 期望integer n,而你给它mwSize n。那是不行的。我从这些问题中遇到了几个困难:总是定义正确的局部变量,你传递给 BLAS/LAPACK 例程,并对它们进行类型转换。尝试在TestBlas 函数中使用int n,并在调用时将size_t 相应地转换为int This link 也应该很有帮助:“mwSignedIndex 通常推荐用于 MATLAB 附带的库的 BLAS 和 LAPACK 函数的整数参数......至少这是示例代码中使用了什么。我没有扫描头文件以查看它是否总是减少到 ptrdiff_t。"。这解释了你的其他警告,这确实会导致问题(int vs long)。 我根据我的最佳猜测添加了一个答案。请检查一下,因为我不确定它是否能解决您的问题。 【参考方案1】:

如果我的怀疑是正确的,您只需定义代码中涉及的整数的正确类型:

  #include <mex.h>
  #include <math.h>
  #include <blas.h>

  void TestBlas(double *L, double *R, mwSignedIndex n) //changed
  

      mwSignedIndex one = 1; //changed
      double sum = ddot(&n,L,&one,L,&one);

      //Output Matrix R not defined, just for test purposes...

   

  void mexFunction( int nlhs, mxArray *plhs[],
                    int nrhs, const mxArray *prhs[])
  
      double *inMatrix;               /* 1xN input matrix */
      size_t ncols;                   /* size of matrix */
      long *ncolsPr;                  /* output matrix */
      double *outMatrix;              /* output matrix */

      inMatrix = mxGetPr(prhs[0]);
      ncols = mxGetN(prhs[0]);

      /* create the output matrix */
      plhs[0] = mxCreateDoubleMatrix((mwSize)1,(mwSize)ncols,mxREAL); //changed
      outMatrix = mxGetPr(plhs[0]);

      TestBlas(inMatrix,outMatrix,(mwSignedIndex)ncols); //changed
  

根据我的经验,您必须特别注意函数调用中出现的文字常量,因此请注意 1(mwSize) 的转换,这是 mxCreateDoubleMatrix 所期望的。

【讨论】:

这是一个非常全面且有用的答案,再次感谢! @user3116232 很高兴能帮上忙。只是要明确一点:这确实解决了您的问题吗?:) 是的,因为我对 BLAS 想要的文件类型感到非常困惑。我仍然是,但现在我知道如何调整我的代码。我猜理解是在路上的;)

以上是关于在 C Mex-File 中使用 BLAS 库的主要内容,如果未能解决你的问题,请参考以下文章

Eigen使用 BLAS/LAPACK 作为 backend

Invalid MEX-file 'E:\vlfeat-0.9.18\toolbox\mex\mexw64\vl_kmeans.mexw64':

将具有外部依赖项的共享库集成到 MATLAB |即犰狳、LAPACK、BLAS

将 C++ 与 BLAS 和 LAPACK 连接起来

将 C++ 与 BLAS 和 LAPACK 连接起来

如何将 lapack 和 BLAS 库链接到 C++ 代码