Pregunta

Estoy escribiendo un programa en C ++ que utiliza la biblioteca CLAPACK ATLAS. Sin embargo, no puedo conseguir el programa para enlazar con éxito a la biblioteca. He escrito un pequeño programa en C para demostrar mejor el problema. Curiosamente, este pequeño enlaces del programa de demostración bien si puedo compilar con GCC, pero me da los mismos errores de enlace cuando intento compilar con G ++. Yo estaba esperando que alguien podría ayudarme a averiguar exactamente lo que G ++ y GCC están haciendo de manera diferente, a fin de obtener el programa original para enlazar (El programa original es un programa en C ++ y no puede simplemente "utilizar GCC")

Aquí está el programa de demostración de pequeña:

#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;
}

Y cuando intento compilar esto con GCC, funciona muy 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

$

Y cuando intento compilar esto con G ++, da errores de enlace:

$ 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
$

Por último, pero no menos importante: Un poco de información acerca de mi sistema:
Sistema operativo: 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)
Bibliotecas:

$ 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

Además, para los puntos de bonificación: ¿Cuál es exactamente la relación histórica y funcional entre LAPACK y ATLAS

?
¿Fue útil?

Solución

Si desea vincular un programa en C ++ para una biblioteca de C que tiene que asegurarse de que todas las funciones, etc., en la biblioteca de C tiene el prefijo extern "C". El compilador C ++ destroza nombres C ++ símbolo que hace que sea imposible que el enlazador para que coincida entonces símbolos con los nombres de la biblioteca C. Se puede utilizar un bloque de declarar sus símbolos C:

extern "C" {
  ...
}

Es posible que pueda definir un símbolo de preprocesador para instruir cblas.h y clapack.h para incluir el extern "C" necesaria frente a todas las declaraciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top