IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

appel de routines fortran depuis un programme en C


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut appel de routines fortran depuis un programme en C
    Bonjour à tous,

    je travaille actuellement sur un programme de cacul vectoriel en C. Pour que celui-ci soit opérationnel, j'ai besoin d'une librairie de calcul du CERN (lapack). Celles-ci sont en fortran. Evidemment le problème c'est que je ne sais absolument pas comment appeller des routines fortran à partir d'un programme en C (bien qu'apparemment ça soit possible).
    J'ai bien cherché avant de poster et n'ai rien trouvé de vraiment "croustillant" à se mettre sous la dent. Si quelqu'un à un lien vers un tuto ou des conseils, je suis preneur!

    Bonne journée à tous!

  2. #2
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par booby
    J'ai bien cherché avant de poster et n'ai rien trouvé de vraiment "croustillant" à se mettre sous la dent.
    Et ca ? Ca devrait au moins donner une piste de demarrage...

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    merci pour ta réponse. je teste et je vous tiens au courant.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    bon, ce coup ci je pense avoir à peu près tout lu, mais, pas tout compris malheureusement...

    Je récapitule:

    je travaille sour red hat (9?).

    j'ai une bibliotheque de routines de calcul du CERN lapack.a, dans lequel je souhaite utiliser une subroutine ssteqr.o. Le tout à partir du programme en C.

    D'apres la documentation la subroutine ssteqr.f ressemble à ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SUBROUTINE SSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO)
    CHARACTER * 1 COMPZ
    INTEGER N, LDZ, INFO
    REAL D(*), E(*), Z(LDZ,*), WORK(*)
    Si j'ai bien compris je dois déclarer la fonction ssteqr dans mon code comme ci dessous:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void ssteqr(char compz, int n, float *d, float *e, float *z, int ldz, int *info);
    maintenant reste à indique au programme C, l'endroit où aller chercher cette fonction (c'est ici que je bloque), d'ou ma question: doit-t-on ajouter un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #include <quelquechose.h>
    ?

    Ensuite pour la compilation (sachant que je fais de la compilation séparée avec gcc), "l'ajout de bibliothèque lors de l'édition de lien" me parait bien obscur...

    Si quelqu'un se sent de m'éclairer un poil, merci pour vos réponses.

  5. #5
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Ta routine Fortran est donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SUBROUTINE SSTEQR( COMPZ, N, D, E, Z, LDZ, WORK, INFO)
    Le compilateur C va attendre un prototype pour cette routine. Il est propre de le mettre dans un fichier entete, ssteqr.h par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #ifndef H_SSTEQR
    #define H_SSTEQR
     
    void ssteqr(char *compz, int *n, float *d, float *e, 
                      float *z, int *ldz, float *work, int *info);
     
    #endif
    Remarque que l'ensemble des parametres sont des pointeurs, car le Fortran utilise toujours un passage par reference (que l'on peut simuler par l'utilisation de pointeurs, en C).

    Tout code C qui utilise ta fonction va #include "ssteqr.h". La compilation va donc bien se passer.

    Ensuite, il y a l'edition de lien, c'est a dire l'ajout du code de SSTEQR pour former l'executable final. Il faut indiquer ou trouver ce code. Dans ton cas, c'est dans la bibliotheque lapack.a. Regarde les options -l et -L de gcc pour assurer le lien (malheureusement, le nom de ta bibliotheque ne respecte pas la convention de nommage lib<something>.a, donc cela complique un peu les choses).

    Enfin, il y a le gros probleme: le tableau a deux-dimensions Z. Et la c'est penible. Fortran est column-major (la dimension la plus a gauche varie le plus vite). C est row-major (la dimension la plus a droite varie le plus vite). Il faut donc s'assurer que les elements sont dans le bon ordre : tu remarqueras que dans le prototype ci-dessus, j'ai mis float *z et non pas **z. Du point de vue de la memoire, le Fortran et le C voient les tableaux multi-dimensionnels comme un seul espace contigu - donc, un tableau a une seule dimension. Le plus simple[1] est donc, dans ton programme C, de declarer z comme etant un tableau a une dimension, puis le remplir en respectant l'ordre attendu par le Fortran.

    [1] le plus simple est evidemment de tout faire en Fortran...

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    Tout d'abord merci pour tes réponses. Je mets ça en application de suite.

    Citation Envoyé par DaZumba
    Enfin, il y a le gros probleme: le tableau a deux-dimensions Z. Et la c'est penible. Fortran est column-major (la dimension la plus a gauche varie le plus vite). C est row-major (la dimension la plus a droite varie le plus vite). Il faut donc s'assurer que les elements sont dans le bon ordre : tu remarqueras que dans le prototype ci-dessus, j'ai mis float *z et non pas **z. Du point de vue de la memoire, le Fortran et le C voient les tableaux multi-dimensionnels comme un seul espace contigu - donc, un tableau a une seule dimension. Le plus simple[1] est donc, dans ton programme C, de declarer z comme etant un tableau a une dimension, puis le remplir en respectant l'ordre attendu par le Fortran.
    Pour ce qui est des indices ça ne devrait pas poser de problèmes, sachant que je travaille avec des matrices carrées symétriques (c'est à dire que la ligne d'indice 1 contient la même chose que la colonne du même indice, ce qui me permet, la plupart du temps de travailler sur une demi-matrice)

    Citation Envoyé par DaZumba
    [1] le plus simple est evidemment de tout faire en Fortran...
    aaaahhh lala... j'aurai du écouter mon directeur, il voulait absolument que je code en fortran... enfin, personne n'est parfait!...

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    Citation Envoyé par DaZumba
    Ensuite, il y a l'edition de lien, c'est a dire l'ajout du code de SSTEQR pour former l'executable final. Il faut indiquer ou trouver ce code. Dans ton cas, c'est dans la bibliotheque lapack.a. Regarde les options -l et -L de gcc pour assurer le lien (malheureusement, le nom de ta bibliotheque ne respecte pas la convention de nommage lib<something>.a, donc cela complique un peu les choses).
    bon alors effectivement ça pose problème... tout se passe bien à la compilation jusqu'a l'édition de lien. Je precise le 'endroit ou se trouve ssteqr.a
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    -L /USERS/monpath/lapack/lapack.a
    et la bibilotheque qu'il doit utiliser et là il m'indique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc: ssteqr.o: No such file or directory
    enfin... donc je voulais juste connaitre les conventions de nommage afin de renommer le lapack.a en quelque chose de mieux...

  8. #8
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par booby
    bon alors effectivement ça pose problème... tout se passe bien à la compilation jusqu'a l'édition de lien.
    Je ne comprends pas trop. Tu disposes d'une bibliotheque (lapack.a) ou d'un fichier objet (ssteqr.o)?
    Si tu as la bibliotheque, alors il faut lier en utilisant:
    qui ira chercher le fichier /path/libtoto.a. Il faut aussi lier avec -lm et -lg2c pour le module en fortran.
    Si tu as le fichier objet (compile avec g77), alors il suffit de l'ajouter sur la ligne de compilation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    gcc main.o ssteqr.o -o myprog -lm -lg2c

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    ok c'est bon, ça marche maintenant. un grand merci a toi!


  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    Je me suis rejoui un peu vite j'ai encore des problemes a la compilation...

    Citation Envoyé par DaZumba
    Je ne comprends pas trop. Tu disposes d'une bibliotheque (lapack.a) ou d'un fichier objet (ssteqr.o)?
    je dispose d'un bibliotheque lapack.a, qui contient une floppee de .o (dont ceux qui m'interessent: ssyev.o et ssteqr.o).

    donc voila mon probleme:

    la ligne de mon Makefile qui me pose probleme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -l ssyev -L /MonPath/lapack Spec2ev.o filework.o out.o vectcomp.o allocate.o -lm -o Spec2ev
    ce que m'indique gcc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    gcc -l ssyev -L /MonPath/lapack Spec2ev.o filework.o out.o vectcomp.o allocate.o -lm -o Spec2ev
    gcc: ssyev: No such file or directory
    make: *** [Spec2ev] Error 1

  11. #11
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    gcc -l ssyev -L /MonPath/lapack Spec2ev.o filework.o out.o vectcomp.o allocate.o -lm -o Spec2ev
    C'est quoi ce ssyev? Ton
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    -l ssyev -L /MonPath/lapack
    signifie que gcc va chercher le fichier /MonPath/lapack/libssyev.a. Bien lire la doc !

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    donc si j'ai bien compris, je dois mettre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -l lapack -L /MonPath/lapack
    pour que gcc recherche liblapack.a dans /MonPath/lapack.

    le probleme c'est que gcc me met:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc: lapack: No such file or directory

  13. #13
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    /MonPath/lapack/liblapack.a existe-t-il?

    Remarque aussi que gcc conseille de ne pas mettre d'espace apres -l et -L. Ce n'est pas la source de ton probleme, mais autant faire les choses bien !
    gcc -llapack -L/MonPath/lapack

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    Citation Envoyé par DaZumba
    /MonPath/lapack/liblapack.a existe-t-il?

    Remarque aussi que gcc conseille de ne pas mettre d'espace apres -l et -L. Ce n'est pas la source de ton probleme, mais autant faire les choses bien !
    gcc -llapack -L/MonPath/lapack
    oui ce fichier existe bien. je viens d'enlever les espaces et le message d'erreur a change:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Spec2ev.o: In function `main':
    /MonPath/SRCPROGZ/Spec2ev/Spec2ev.c:55: undefined reference to `ssyev'
    collect2: ld returned 1 exit status
    make: *** [Spec2ev] Error 1
    ssyev etant la routine fortran que j'appelle.
    sachant que ssyev.o est contenu dans liblapack.a...

  15. #15
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par booby
    /MonPath/SRCPROGZ/Spec2ev/Spec2ev.c:55: undefined reference to `ssyev'
    On avance. Je suis surpris que supprimer les espaces ait arrange le probleme a ce point. Dans la doc, ils ne disent pas que les espaces sont aussi importants, mais c'est toujours bon a savoir !

    Pour ton probleme d'edition de lien, l'editeur de lien cherche une fonction appelee ssyev qu'il ne trouve nul part alors que tu dis qu'elle se trouve dans la bibliotheque liblapack.a. Mais les compilateurs Fortran ont la facheuse tendance de 'decorer' les noms de fonction : g77, par exemple, ajoute un underscore apres le nom. D'autres compilateurs ont d'autres habitudes (pas de changement, deux underscores, ...). Ton ssyev s'appelle donc peut etre ssyev_ (tu peux utiliser ar ou nm pour connaitre le nom exact des fonctions mises a disposition par la bibliotheque).

    Personnellement, j'utilise une petite macro des que j'utilise une fonction Fortran dans un programme C, pour ajouter cet underscore:
    Un petit fichier header, a inclure dans toute unite C qui appelle une fonction Fortran:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #ifndef H_PF
    #define H_PF
     
    #define PF(name) name##_
     
    #endif
    Et on remplace:
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      PF(ssyev)(x, y, z);
    L'interet de faire une macro est qu'il est facile de s'adapter aux habitudes de differents compilateurs Fortran...

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    Merci pour ta patience ainsi que pour tes lignes de code qui m'aident beaucoup.
    Je viens d'inclure le "H_PF" et j'obtiens le meme type d'erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /USERS/tsieroci/SRCPROGZ/Spec2ev/Spec2ev.c:56: undefined reference to `ssyev_'
    collect2: ld returned 1 exit status
    make: *** [Spec2ev] Error 1
    j'en deduit que la "decoration" ajoutee par le compilateur fortran n'est pas _

    Citation Envoyé par DaZumba
    (tu peux utiliser ar ou nm pour connaitre le nom exact des fonctions mises a disposition par la bibliotheque).
    j'ai fait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nm /MonPath/lapack/libpack.a
    voila ce que j'ai obtenu sur ssyev.o

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ssyev.o:
    00000000 t gcc2_compiled.
             U ilaenv_
             U lsame_
             U slamch_
             U slansy_
             U slascl_
             U sorgtr_
             U sqrt
             U sscal_
             U ssteqr_
             U ssterf_
    00000000 T ssyev_
             U ssytrd_
             U xerbla_

  17. #17
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    La decoration est donc bien la. J'avoue ne pas comprendre pourquoi l'editeur de lien ne trouve pas la fonction...

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    ok, j'ai sans doute fait une erreur ailleurs... je verrai ca demain, encore merci pour ton aide.

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 47
    Par défaut
    bon alors ça y ça compile!

    Ce matin en lancant un:

    sur le serveur, je me rends compte que la librairie est presente dans le repertoire j'ai donc remplacé mon ce qui donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -llapack -L/usr/lib/ Spec2ev.o filework.o out.o vectcomp.o allocate.o -lm -lg2c -o Spec2ev
    et maintenant la compilation se déroule sans problème!... Je ne m'explique pas le pourquoi du comment mais en tous cas ça compile.

    Encore merci DaZumba! chapeau!

  20. #20
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par booby
    Je ne m'explique pas le pourquoi du comment mais en tous cas ça compile.
    C'est un bon debut -- il n'y a plus qu'a esperer que ton programme donne les bons resultats, maintenant. Une petite remarque: comme /usr/lib est le repertoire d'installation des bibliotheques (libm et libg2c y sont) par defaut, il n'est pas utile de le preciser avec l'option -L.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Exécution d'une DLL Fortran depuis un programme Java - JNA
    Par Anthony BIGET dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 28/07/2014, 10h58
  2. Appel de fonction Fortran via un programme C
    Par bybby83 dans le forum Fortran
    Réponses: 3
    Dernier message: 08/01/2009, 10h08
  3. Appel de DLL MATLAB depuis un programme C
    Par jericho dans le forum MATLAB
    Réponses: 1
    Dernier message: 18/02/2008, 16h09
  4. Appel de routine MATLAB depuis Java
    Par habasque dans le forum MATLAB
    Réponses: 4
    Dernier message: 24/09/2007, 18h56
  5. Appel de DLL Fortran depuis C/C++
    Par ultimate_manx dans le forum Fortran
    Réponses: 3
    Dernier message: 31/05/2007, 13h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo