J'écris un programme en C++ qui utilise la bibliothèque CLAPACK ATLAS. Cependant, je ne parviens pas à lier correctement le programme à la bibliothèque. J'ai écrit un petit programme C pour mieux démontrer le problème. Chose intéressante, ce petit programme de démonstration est très bien si je le compile avec GCC, mais j'ai les mêmes erreurs d'éditeur de liens quand j'essaie de compiler avec G ++. J'espérais que quelqu'un pourrait m'aider à comprendre exactement ce que G ++ et GCC font différemment, afin de lier le programme original (Le programme original est un programme C++ et je ne peux pas simplement "utiliser GCC")C C++ Erreur de liaison
Voici le petit programme de démonstration:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <cblas.h>
#include <clapack.h>
// a is a column-major array of all the values in the matrix to invert
// The matrix's height and width are the same because it is a square matrix.
void invertMatrix(float *a, unsigned int height)
{
int info, ipiv[height];
info = clapack_sgetrf(CblasColMajor, height, height, a, height, ipiv);
info = clapack_sgetri(CblasColMajor, height, a, height, ipiv);
}
void displayMatrix(float *a, unsigned int height, unsigned int width)
{
int i, j;
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
{
printf("%1.3f ", a[height*j + i]);
}
printf("\n");
}
printf("\n");
}
void multiplyMatrix(float *a, unsigned int aheight, unsigned int awidth, float *b, unsigned int bwidth, float *c)
{
cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, aheight, bwidth, awidth, 1.0f, a, aheight, b, awidth, 0.0f, c, aheight);
}
int main(int argc, char *argv[])
{
int i;
float a[9], b[9], c[9];
srand(time(NULL));
for(i = 0; i < 9; i++)
{
a[i] = 1.0f*rand()/RAND_MAX;
b[i] = a[i];
}
displayMatrix(a, 3, 3);
invertMatrix(a, 3);
multiplyMatrix(a, 3, 3, b, 3, c);
displayMatrix(c, 3, 3);
return 0;
}
Et quand je tente de compiler ce avec GCC, il fonctionne très bien:
$ gcc -o linearalgebra linearalgebra.c -I /usr/include/atlas -L /usr/lib64/atlas/ -llapack -lblas
$ ./linearalgebra
0.723 0.755 0.753
0.179 0.912 0.349
0.642 0.265 0.530
1.000 -0.000 0.000
0.000 1.000 0.000
0.000 0.000 1.000
$
Et quand je tente de compiler cela avec G ++, il donne des erreurs d'éditeur de liens :
$ g++ -o linearalgebra linearalgebra.c -I /usr/include/atlas -L /usr/lib64/atlas/ -llapack -lblas
/tmp/ccuhmDKE.o: In function `multiplyMatrix(float*, unsigned int, unsigned int, float*, unsigned int, float*)':
linearalgebra.c:(.text+0x7b): undefined reference to `cblas_sgemm(CBLAS_ORDER, CBLAS_TRANSPOSE, CBLAS_TRANSPOSE, int, int, int, float, float const*, int, float const*, int, float, float*, int)'
/tmp/ccuhmDKE.o: In function `invertMatrix(float*, unsigned int)':
linearalgebra.c:(.text+0x182): undefined reference to `clapack_sgetrf(CBLAS_ORDER, int, int, float*, int, int*)'
linearalgebra.c:(.text+0x1a0): undefined reference to `clapack_sgetri(CBLAS_ORDER, int, float*, int, int const*)'
collect2: ld returned 1 exit status
$
Last but not least: Quelques informations sur mon système:
Système d'exploitation: Fedora 10 (Linux hostname 2.6.27.25-170.2.72.fc10.x86_64 #1 SMP Sun Jun 21 18:39:34 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux)
Bibliothèques:
$ yum list | grep lapack
lapack.x86_64 3.1.1-4.fc10 installed
lapack-debuginfo.x86_64 3.1.1-4.fc10 installed
lapack-devel.x86_64 3.1.1-4.fc10 @fedora
$ yum list | grep blas
blas.x86_64 3.1.1-4.fc10 installed
blas-devel.x86_64 3.1.1-4.fc10 installed
$ yum list | grep atlas
atlas.x86_64 3.6.0-15.fc10 installed
atlas-debuginfo.x86_64 3.6.0-15.fc10 installed
atlas-devel.x86_64 3.6.0-15.fc10 @fedora
En outre, pour les points de bonus: Quelle est exactement la relation historique et fonctionnelle entre LAPACK et ATLAS?
Merci, Martin. J'ai enveloppé la lapack et blas les en-têtes #include dans un bloc externe "C" {}, et maintenant cela fonctionne avec G ++, parce que G ++ sait ne pas altérer les noms quand ils rencontrent la déclaration. – Litherum