Question

Je suis en train d'écrire un programme en C ++ qui utilise la bibliothèque CLAPACK ATLAS. Cependant, je ne peux pas obtenir le programme avec succès pour relier à la bibliothèque. J'ai écrit un petit programme C pour mieux démontrer le problème. Il est intéressant, ce petit liens du programme de démonstration très bien si je le compiler avec GCC, mais je reçois les mêmes erreurs de l'éditeur de liens lorsque je tente de compiler avec G ++. J'espérais que quelqu'un pourrait me aider à comprendre exactement ce que G ++ et GCC font différemment, de manière à obtenir le programme original de lien (Le programme original est un programme C ++ et je ne peux pas simplement « utiliser GCC »)

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 de l'é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 bonus: Quelle est exactement la relation historique et fonctionnelle entre LAPACK et ATLAS

?
Était-ce utile?

La solution

Si vous souhaitez lier un programme C ++ à une bibliothèque C vous devez vous assurer que toutes les fonctions, etc. dans la bibliothèque C est préfixé par extern "C". Le compilateur C ++ mutile noms C ++ symbole qui rend impossible pour l'éditeur de liens pour correspondre alors des symboles avec les noms dans la bibliothèque C. Vous pouvez utiliser un bloc pour déclarer vos symboles C:

extern "C" {
  ...
}

Vous pourrez peut-être définir un symbole de préprocesseur pour instruire cblas.h et clapack.h d'inclure le extern "C" nécessaire devant toutes les déclarations.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top