Instalando uma implementação abrangente do LAPACK no Ubuntu

5

Gostaria de perguntar como instalar corretamente um pacote LAPACK abrangente como e. é oferecido pelo pacote do Gentoo 'sci-libs / clapack' dentro de um Ubuntu meio ambiente.

Eu não estou falando sobre o atlas aqui, que oferece apenas uma pequena parte do lapack funcionalidade, mas uma solução mais geral que oferece funções para, e. eigen valor problemas como 'dstegr'.

Aqui está o que consegui até agora: Meu comando de pesquisa favorito

apt-file search clapack.h

ofereceu apenas duas fontes possíveis.

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

Como mencionado, a versão do atlas não é o que eu quero. A variação da libfreefem por outro lado, lê-se bem. Então

apt-get install libfreefem++-dev

Além disso

apt-cache search lapack

oferece muito, as linhas de aparência mais promissoras sendo

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

o primeiro pacote do qual eu instalei. Agora adicionando

#include <freefem++/clapack.h>

no meu programa retorna uma longa lista compreensível de erros no estilo

'integer', 'real', 'doublereal', ... não foi declarado neste escopo

como na verdade eles não eram. De qualquer forma eu não estou olhando para freefem ou atlas, mas apenas uma implementação LAPACK utilizável em execução existe realmente nada disso para o Ubuntu?

Relendo meu próprio post Acredito que a pergunta também pode ser resumida a "Onde posso obter um arquivo de cabeçalho abrangente para 'liblapack-dev'"?

    
por Markus-Hermann 07.02.2014 / 15:59

2 respostas

6

Encontrei uma solução que funciona para mim. A linha inferior para aqueles que podem ler isso mais tarde e com um problema semelhante: Eu fui para a página inicial do LAPACK , baixada a versão mais recente do LAPACK como um tar gz, descompactou e seguiu as instruções emitidas no guia de instalação no mesmo site. Problema que encontrei: No Makefile eu tive que reduzir a linha

all: lapack_install lib blas_testing lapack_testing

para

all: lapack_install lib

Depois disso

make

me deu ./liblapack.a e ./libtmglib.a.

Tanto assim Fortran. No entanto, quero algo para inserir em um programa em C. Isso significa que eu também quero o LAPACKE.

Ele pode ser encontrado no subdiretório ./lapacke/. Há um CMakeLists.txt que eu ignorei, chamando o Makefile já presente diretamente (ele é curto e fácil de ler e usa o arquivo make.inc que você cria quando segue o guia de instalação mencionado acima) . A única desvantagem aqui era a falta de lapacke_mangling.h que eu tinha que copiar para ./lapacke/include /.

Isso fez a chamada para "fazer" de dentro do diretório ./lapacke/ correu sem problemas para criar ./lapacke.a e eu estava pronto para escrever um pequeno programa de demonstração:

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

Qual no meu sistema agora produz a saída

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

Em termos de BLAS eu instalei

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

Consequentemente, no Makefile principal do Lapack, usei

BLASLIB = /usr/lib/openblas-base/libopenblas.a
    
por Markus-Hermann 10.02.2014 / 16:49
8

Eu obtive o mesmo resultado usando o gerenciador de pacotes. Eu fiz o seguinte:

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

As bibliotecas foram incluídas em / usr / lib e as inclusões em / usr / include.

Obrigado a Markus-Hermann pelo exemplo de código no post anterior. Isso me ajudou a testá-lo bem rápido. Usando os diretórios de instalação padrão, usei o seguinte comando:

g++ svd_demo.cpp -I"/usr/include" -L"/usr/lib" -llapacke -lblas
    
por GreenEye 22.12.2014 / 17:44