Lapack in VS verwenden, Routine wird als unresolved external symbol abgestempelt



  • Hallo zusammen 🙂

    Wieder einmal eine Herausforderung mit der ich alleine nicht fertig werde 🙂

    Und zwar geht es darum, dass ich allein mit ublas numerisch nicht effizient genug bin, deshalb hab ich die boost-numeric-bindings und die LAPACK-Bibliotheken runtergeladen und in meinem Projekt eingebunden.
    Die Lapack-Funktionaltitäten will ich in einem kleinen Programm testen:

    #include <stdio.h>
    #include <fstream>
    
    #include <boost/numeric/bindings/traits/ublas_matrix.hpp>
    #include <boost/numeric/ublas/matrix_proxy.hpp>
    #include <boost/numeric/ublas/vector.hpp>
    #include <boost/numeric/ublas/symmetric.hpp>
    #include <boost/numeric/ublas/io.hpp>
    #include <boost/numeric/ublas/lu.hpp>
    
    #include <boost/numeric/bindings/lapack/gesv.hpp>
    
    using namespace boost::numeric::ublas;
    using namespace boost::numeric::bindings::lapack;
    
    extern "C" void dgesv(const int *N, const int *nrhs, double *A, const int *lda, int
    	*ipiv, double *b, const int *ldb, int *info);
    
    int main(int argc, char** argv){
    
    	ublas::matrix <double> A(3, 3);
    	ublas::matrix <double> b(3, 1);
    
        /* 3x3 matrix A
         * 76 25 11
         * 27 89 51
         * 18 60 32
         */
        A(0, 0) = 76.0;
    	A(0, 1) = 25.0;
    	A(0, 2) = 11.0;
    	A(1, 0) = 27.0;
    	A(1, 1) = 89.0;
    	A(1, 2) = 51.0;
    	A(2, 0) = 18.0;
    	A(2, 1) = 60.0;
    	A(2, 2) = 32.0;
    
    	b(0, 0) = 10.0;
    	b(1, 0) = 7.0;
    	b(2, 0) = 43.0;
    
        int info = boost::numeric::bindings::lapack::gesv(A, b);    
    
        if(info == 0) /* succeed */
    	printf("The solution is %lf %lf %lf\n", b[0], b[1], b[2]);
        else
    	fprintf(stderr, "dgesv_ fails %d\n", info);
    
    	return 0;
    
    };
    

    Kompiliert wird es, beim Linken bekomm ich aber LNK2019:

    Start.obj : error LNK2019: unresolved external symbol _dgesv referenced in function "void __cdecl boost::numeric::bindings::lapack::detail::gesv(int,int,double *,int,int *,double *,int,int *)" (?gesv@detail@lapack@bindings@numeric@boost@@YAXHHPANHPAH0H1@Z)

    Die entsprechende Methode in gesv.hpp:

    inline 
          void gesv (int const n, int const nrhs,
                     double* a, int const lda, int* ipiv, 
                     double* b, int const ldb, int* info) 
          {
            LAPACK_DGESV (&n, &nrhs, a, &lda, ipiv, b, &ldb, info);
          }
    

    Hier http://www.c-plusplus.net/forum/276758?highlight=lnk2019+extern hab ich zwar was zum Thema gefunden, aber das Problem hab ich immer noch.

    Beispiel stammt aus http://icl.cs.utk.edu/lapack-for-windows/index.html und http://www.cs.rochester.edu/~bh/cs400/using_lapack.html

    Vieelen lieben Dank an alle die es sich anschauen 🙂



  • Du hast die Implementierung deiner Funktion

    extern "C" void dgesv(const int *N, const int *nrhs, double *A, const int *lda, int
        *ipiv, double *b, const int *ldb, int *info);
    

    nicht zum Programm gebunden.



  • Ähm .. Ich weiß nciht ob ich dich richtig versteh. Die (Fortran-)Implementierung der Funktion hab ich mittels Project-Properties -> C++ -> General -> Additional Include Directories -> LAPACK_3.1.1\src (wo sich dgesv.f befindet).

    Nun ist meine Denkweise folgende: gesv.hpp überlädt die Methode gesv je nach übergebenen Matrix-Typen und ruft die entsprechende Fortran-Routine auf (dgesv/zgesv/..). Diese rechnet meine Matrizen, und alle sind glücklich. Doch ich bin grad nicht sonderlich glücklich. Also irgendwo unterwegs stimmt was in meiner Logik nicht 🙂

    Oder meintest du mit Implementierung der Funktion was anderes?



  • Die Funktion sollte doch in einer DLL stecken und daher als Bibliothek eingebunden werden. Mit Includepfaden hat das nichts zu tun.
    Wenn du nur den Sourcecode von LAPACK hast, wirst du die DLL erst mal bauen müssen.



  • Ach so. Ja doch, da ist z. B. LAPACKd.lib (muss doch nicht unbedingt dynamisch sein, oder?), die ich auch eingebunden habe. Ich hab irgendwo was ähnliches gefunden, wo es stand dass in der lib die Methode möglicherweise anders geführt wird, als dgesv_ oder _dgesv_ und deshalb nicht gefunden wird. Hab ich mit VS geöffnet und gefunden - ist aber nicht, ist ganz normal dgesv 🙄 Hast du noch nen Tipp?



  • Tja, dann weiß ich auch nicht ...



  • So, neue Woche, neues Glück, denselben Streß mit diesen Libs 😃 Also her mit den frischen Ideen zum Thema 😃

    Danke alle und den Valentinstag nicht vergessen (Notlösung: Schokolade und Blumen, ist immer ein Hit 😃 )


Anmelden zum Antworten