在 Ubuntu 下安装一个全面的 LAPACK 实现

Mar*_*ann 6 programming c software-installation

我想问一下如何正确安装一个综合的 LAPACK 包,例如在 Ubuntu 环境中由 Gentoo 包“sci-libs/clapack”提供。

我在这里不是在谈论图集,它只提供了 lapack 功能的一小部分,而是一个更通用的解决方案,提供了诸如“dstegr”之类的特征值问题的功能。

这是我到目前为止所取得的成就:我最喜欢的搜索命令

apt-file search clapack.h
Run Code Online (Sandbox Code Playgroud)

只提供了两种可能的来源。

libatlas-dev: /usr/include/atlas/clapack.h
libfreefem++-dev: /usr/include/freefem++/clapack.h
Run Code Online (Sandbox Code Playgroud)

如前所述,地图集版本不是我想要的。另一方面,libfreefem 变体读起来很好。所以

apt-get install libfreefem++-dev
Run Code Online (Sandbox Code Playgroud)

此外

apt-cache search lapack
Run Code Online (Sandbox Code Playgroud)

提供了很多,最有前途的线是

liblapack-dev - library of linear algebra routines 3 - static version
liblapack3gf - library of linear algebra routines 3 - shared version
Run Code Online (Sandbox Code Playgroud)

我安装的第一个包。现在添加

#include <freefem++/clapack.h>
Run Code Online (Sandbox Code Playgroud)

进入我的程序会返回一长串可理解的样式错误列表

'integer', 'real', 'doublereal', ... 未在此范围内声明

事实上他们不是。无论如何,我不是在寻找 freefem 或 atlas,而是在寻找一个正在运行的、可用的 LAPACK 实现,Ubuntu 真的没有这样的东西吗?

重读我自己的帖子,我相信这个问题也可能归结为“我在哪里可以获得‘liblapack-dev’的综合头文件”?

小智 8

我通过使用包管理器得到了相同的结果。我做了以下事情:

sudo apt-get install libblas-dev checkinstall
sudo apt-get install libblas-doc checkinstall
sudo apt-get install liblapacke-dev checkinstall
sudo apt-get install liblapack-doc checkinstall
Run Code Online (Sandbox Code Playgroud)

库在 /usr/lib 中,包含在 /usr/include 中。

感谢Markus-Hermann在上一篇文章中提供的示例代码。它帮助我快速测试了它。使用默认安装目录,我使用了以下命令:

g++ svd_demo.cpp -I"/usr/include" -L"/usr/lib" -llapacke -lblas
Run Code Online (Sandbox Code Playgroud)


Mar*_*ann 7

找到了适合我的解决方案。对于那些可能会在稍后阅读并遇到类似问题的人来说,底线是:我去了LAPACK 主页,下载了最新版本的 LAPACK 作为 tar gz,解压并按照安装指南发布说明进行操作同一个网站。我遇到的麻烦:在 Makefile 中,我不得不减少行

all: lapack_install lib blas_testing lapack_testing
Run Code Online (Sandbox Code Playgroud)

all: lapack_install lib
Run Code Online (Sandbox Code Playgroud)

在那之后

make
Run Code Online (Sandbox Code Playgroud)

给了我 ./liblapack.a 和 ./libtmglib.a。

这么多Fortran。但是,我想要插入 C 程序的东西。这意味着我也想要 LAPACKE。

它可以在子目录 ./lapacke/ 中找到。有一个我忽略的 CMakeLists.txt,直接调用了已经存在的 Makefile(它简短易读,它使用你按照上面提到的安装指南创建的 make.inc 文件)。这里的一个缺点是缺少lapacke_mangling.h,我必须将其复制到 ./lapacke/include/ 中。

这完成了从目录 ./lapacke/ 内部调用“make”的操作,创建 ./lapacke.a 没有问题,我准备编写一个小演示程序:

/**
 * svd_demo.cpp
 * 
 * Given that you put version 3.5.0 into /opt/lapack/ compile this with: 
 * g++ svd_demo.cpp -I"/opt/lapack/lapack-3.5.0/lapacke/include" \
 *   -L"/opt/lapack/lapack-3.5.0" -llapacke -llapack -lblas -lcblas
 * The order of included libraries is important!
 */

#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
#include <cblas.h>
#include <lapacke.h>

using namespace std;

typedef double value;

/** Column major style! */
string matrix2string(int m, int n, value* A)
{
  ostringstream oss;
  for (int j=0;j<m;j++)
  {
    for (int k=0;k<n;k++)
    {
      oss << A[j+k*m] << "\t";
    }
    oss << endl;
  }
  return oss.str();
}

int main(int argc, char** argv)
{
  //> Part 1. Decomposition. -----------------------------------------
  char jobu  = 'A'; // Return the complete matrix U
  char jobvt = 'A'; // Return the complete matrix VT
  int mA = 2;
  int nA = 3;
  int lda = 2;
  int ldu = 2;
  int ldvt = 3;
  int lwork = 81;
  int info = 0;
  value* A = (value*)malloc(mA*nA*sizeof(value));
  value* U = (value*)malloc(mA*mA*sizeof(value));
  value* VT = (value*)malloc(nA*nA*sizeof(value));
  value* Svec = (value*)malloc(3*sizeof(value));
  value* work = (value*)malloc(lwork*sizeof(value));

  A[0] = 1; A[2] = 2; A[4] = 4;
  A[1] = 0; A[3] = 0; A[5] = 4;

  cout << "Matrix A (will be overwritten, as is documented):" << endl <<
    matrix2string(mA,nA,A);

  // Citing lapacke.h
  //lapack_int LAPACKE_dgesvd(int matrix_order, char jobu, char jobvt,
  //   lapack_int m, lapack_int n, double* a,
  //   lapack_int lda, double* s, double* u, lapack_int ldu,
  //   double* vt, lapack_int ldvt, double* superb);

  info = LAPACKE_dgesvd(LAPACK_COL_MAJOR, jobu, jobvt, mA, nA, A, lda, Svec, U, ldu, VT, ldvt, work);
  cout << "Ran dgesvd. Let's see ..." << endl <<
    "U:" << endl << matrix2string(mA,mA,U) <<
    "Svec:" << endl << matrix2string(1,nA,Svec) <<
    "VT:" << endl << matrix2string(nA,nA,VT) <<
    "Info Code: " << info << endl << endl <<
    "All is well." << endl;
  //< ----------------------------------------------------------------
  //> Part 2. Checking the result. -----------------------------------
  value* S = (value*)malloc(mA*nA*sizeof(value));
  S[0] = Svec[0]; S[2] = 0      ; S[4] = 0      ;
  S[1] = 0      ; S[3] = Svec[1]; S[5] = 0      ;

  // Citing cblas.h
  // void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
  //   const enum CBLAS_TRANSPOSE TransB, const int M, const int N,
  //   const int K, const double alpha, const double *A,
  //   const int lda, const double *B, const int ldb,
  //   const double beta, double *C, const int ldc);

  // work := S*VT; (2x3)=(2x3)*(3x3)
  cblas_dgemm(CblasColMajor,CblasNoTrans,CblasNoTrans,mA,nA,nA,1,S,lda,VT,ldvt,0,work,lda)    ;
  cout << "Step 1: S*VT" << endl << matrix2string(2,3,work);

  // A := U*work; (2x2)*(2x3)
  cblas_dgemm(CblasColMajor,CblasNoTrans,CblasNoTrans,mA,nA,mA,1,U,ldu,work,lda,0,A,lda);
  cout << "A := U*S*VT:" << endl << matrix2string(mA,nA,A) << endl;
  //< ----------------------------------------------------------------
  free(A); free(U); free(VT); free(Svec); free(work); free(S);
  return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

现在在我的系统上产生输出

1       2       4
0       0       4
Ran dgesvd. Let's see ...
U:
-0.759729       -0.65024
-0.65024        0.759729
Svec:
5.89017 1.51851 0
VT:
-0.128982       -0.257965       -0.957506
-0.42821        -0.856419       0.288414
-0.894427       0.447214        -7.48099e-18
Info Code: 0

All is well.
Step 1: S*VT
-0.759729       -1.51946        -5.63988
-0.65024        -1.30048        0.437958
A := U*S*VT:
1       2       4
-9.63558e-16    -4.86265e-17    4
Run Code Online (Sandbox Code Playgroud)

就我安装的 BLAS 而言

libblas-dev - Basic Linear Algebra Subroutines 3, static library
libblas3gf - Basic Linear Algebra Reference implementations, shared library
libopenblas-dev - Optimized BLAS (linear algebra) library based on GotoBLAS2
Run Code Online (Sandbox Code Playgroud)

因此在我使用的 Lapack 主 Makefile 中

BLASLIB = /usr/lib/openblas-base/libopenblas.a
Run Code Online (Sandbox Code Playgroud)