web-dev-qa-db-fra.com

Installation d'une implémentation complète de LAPACK sous Ubuntu

Je voudrais demander comment installer correctement un paquet LAPACK complet comme par exemple. est proposé par le paquet Gentoo 'sci-libs/clapack' dans un environnement Ubuntu.

Je ne parle pas d’atlas ici, qui ne propose qu’une petite partie des fonctionnalités de lapack, mais une solution plus générale offrant des fonctions pour, par exemple, Des problèmes de valeurs propres comme 'dstegr'.

Voici ce que j'ai réalisé jusqu'à présent: Ma commande de recherche préférée

apt-file search clapack.h

offert que deux sources possibles.

libatlas-dev: /usr/include/atlas/clapack.h
libfreefem++-dev: /usr/include/freefem++/clapack.h

Comme mentionné, la version de l'atlas n'est pas ce que je veux. La variante libfreefem, par contre, se lit bien. Alors

apt-get install libfreefem++-dev

En outre

apt-cache search lapack

offre beaucoup, les lignes les plus prometteuses étant

liblapack-dev - library of linear algebra routines 3 - static version
liblapack3gf - library of linear algebra routines 3 - shared version

le premier paquet que j'ai installé. Maintenant ajouter

#include <freefem++/clapack.h>

dans mon programme retourne une longue liste compréhensible d'erreurs dans le style

'entier', 'real', 'doublereal', ... n'a pas été déclaré dans cette portée

comme en fait ils ne l'étaient pas. De toute façon, je ne cherche pas de freefem ou d’atlas mais juste une implémentation LAPACK en cours d’utilisation, n’est-ce pas vraiment une telle chose pour Ubuntu?

En relisant mon propre message, je pense que la question pourrait également se résumer à "Où puis-je obtenir un fichier d’en-tête complet pour 'liblapack-dev'"?

5
Markus-Hermann

J'ai trouvé une solution qui fonctionne pour moi. La ligne du bas pour ceux qui pourraient lire ceci plus tard et avec un problème similaire: je suis allé à la page d'accueil de LAPACK , j'ai téléchargé la version la plus récente de LAPACK sous la forme d'un fichier tar gz, je l'ai décompressée et j'ai suivi le instructions fournies sur le guide d'installation sur le même site. Problème rencontré: dans le Makefile, je devais réduire la ligne

all: lapack_install lib blas_testing lapack_testing

à

all: lapack_install lib

Après ça

make

m'a donné ./liblapack.a et ./libtmglib.a.

Tellement Fortran. Cependant, je veux quelque chose à insérer dans un programme C. Cela signifie que je veux aussi LAPACKE.

On peut le trouver dans le sous-répertoire ./lapacke/. Il y a un fichier CMakeLists.txt que j'ai ignoré, appelant directement le Makefile déjà présent (il est court et facile à lire et il utilise le fichier make.inc que vous créez lorsque vous suivez le guide d'installation mentionné aboce). Seul inconvénient ici était le manque de lapacke_mangling.h que je devais copier dans ./lapacke/include/.

Ceci a fait l'appel à "make" depuis le répertoire ./lapacke/ s'est déroulé sans problème pour créer ./lapacke.a et j'étais prêt à écrire un petit programme de démonstration:

/**
 * 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;
}

Qui sur mon système produit maintenant la sortie

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

En termes de BLAS j'ai installé

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

En conséquence, dans le Makefile principal de Lapack que j'ai utilisé

BLASLIB = /usr/lib/openblas-base/libopenblas.a
6
Markus-Hermann

J'ai eu le même résultat en utilisant le gestionnaire de paquets. J'ai fait ce qui suit:

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

Les bibliothèques sont entrées dans/usr/lib et les includes dans/usr/include.

Merci à Markus-Hermann pour l'exemple de code dans le post précédent. Cela m'a aidé à le tester très rapidement. En utilisant les répertoires d'installation par défaut, j'ai utilisé la commande suivante:

g++ svd_demo.cpp -I"/usr/include" -L"/usr/lib" -llapacke -lblas
8
GreenEye