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

Fortran Discussion :

Passage de fortran77 à fortran90: problème de passage en argument de tableaux


Sujet :

Fortran

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Août 2011
    Messages : 49
    Points : 50
    Points
    50
    Par défaut Passage de fortran77 à fortran90: problème de passage en argument de tableaux
    Bonjour à tous,

    Mon problème est le suivant: j'ai besoin de récupérer des subroutines faites en fortran 77 afin de les intégrées dans un code en fortran 90. Et il se trouve que j'ai un petit problème lors du passage de tableau en arguments.

    Supposons que j'ai un tableau du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    real, dimmension(l,m,n):: mat
    celui-ci est passé en argument de la subroutine toto dans une boucle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    do i=1,n
         toto(mat(1,1,i))
    end do
    Cependant à l'interrieur de la subroutine toto, ma variable n'est pas déclarée comme un réel tout bête mais comme un tableau:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    subroutine toto (lala)
     
    real, dimension(l,m)::lala
     
    .....
     
    end subroutine toto
    J'ai fait des impressions dans des fichiers et j'ai remarqué que:
    - "mat" est la même en f77 et en f90
    - "mat(1,1, : )" est également le même AVANT de rentrer dans toto
    - "lala" est totalement différent entre f77 et f90

    Je pense que c'est un problème du au fait que les tableaux ne vont pas être lus de la même manière, l'adressage ne se fait pas pareil. Mais je n'ai aucune idée de comment vérifier comment cela fonctionne en détaille et comment modifier le code en conséquence.

    Je sais par exemple que en f77 je pourrais écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    do i=1, l*n*m
         mat(i,1,1)
    end do
    et que cela ne créera pas de dépassement de l'indice car fortran 77 incrémente AUTOMATIQUEMENT les arguments du tableau suivant...

    y-a-t-il une règle comme celle-ci sur la manière dont la subroutine toto va lire ma variable d'entrée qui puisse faire que à l'intérieur de celle-ci ma variable n'est plus la même ?

    Je suis vraiment bloqué, j'ai regardé des tableaux de chiffre toute la journée pour voir comment cela fonctionne mais je n'y parviens pas.

    Merci beaucoup pour votre précieuse aide.


  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Du Fortran 77, c'est un sous-ensemble de Fortran 90. On ne passe pas de Fortran 77 à Fortran 90, au plus, on peut utiliser des fonctionnalités de Fortran 90 non disponibles dans le sous-ensemble Fortran 77...

    Ainsi, il n'y a pas de raison que ton programme écrit pour un compilateur Fortran 77 ne fonctionne pas directement sans changement avec un compilateur Fortran 90 (ou 95 en fait puisque des compilateurs Fortran 90, c'est devenu très très rare...). Le tout sous réserve que ton programme initial soit bien en Fortran 77 et non quelque chose plein d'extensions propriétaire.

    Pour revenir à ton problème, je ne vois pas dans tes extraits ce qui ne fonctionne pas. Tout me semble tout à fait normal. Tu devras préciser ce que tu fais plus précisément.

    Ensuite, quand tu dis : « Je pense que c'est un problème du au fait que les tableaux ne vont pas être lus de la même manière, l'adressage ne se fait pas pareil. », ça dépend de ce que tu fais réellement. Si tu as changé le type d'argument de toto, passant de real lala(l,m) à real, dimension(:, :: lala, ça se peut que ça ne marche plus, mais ce n'est pas ce qu'indique tes extraits de code.

    Ton exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    do i=1, l*n*m
         mat(i,1,1)
    end do
    est illégal (au sens de la norme), mais est acceptable pour tous les compilateurs Fortran que j'ai utilisé depuis Fortran 66. Et ce genre de stratégie est utilisé par plein de programmeurs depuis toujours. Si ce code fonctionne, ce n'est pas par magie (à la « incrémente AUTOMATIQUEMENT les arguments du tableau suivant »), c'est simplement que dans la mémoire, l'élément (1,2,1) suit immédiatement l'élément (l,1,1) et qu'en débordant le premier indice à l+1, tu te trouves à être rendu à l'adresse de l'élément (1,2,1). De la même façon, (l*m+1,1,1) pointe au même endroit que (1,1,n).

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Août 2011
    Messages : 49
    Points : 50
    Points
    50
    Par défaut
    Ainsi, il n'y a pas de raison que ton programme écrit pour un compilateur Fortran 77 ne fonctionne pas directement sans changement avec un compilateur Fortran 90
    Oui, c'est ce que je pensais aussi, mais en faisant un simple copier coller des subroutines du codes en f77 réunies dans un même module de f90 j'ai eu des surprises... par exemple cet histoire de dépassement de tableau. Le code f77 incrémentait tout seul mais pas celui en f90 qui m'annonçait une erreur de dépassement et donc ne compilait pas.

    Enfin voilà. ça plus quelque changements mineures, le code esst en gros le même. pourtant je n'ai pas la même chose.

    Ok, alors tout d'abord je compile avec ifort. Ensuite mes fichier f77 sont en .f et les fichiers f90 sont en .f90. Normal quoi.

    Alors je vais pas mettre tout le module car il est un peu long mais juste le bout de sous-routine qui nous intéresse:

    dans le module f90 ma sous-routine est ainsi:

    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    subroutine read_1_mat(filename)
     
      implicit none
     
      character(len=512) :: filename
      character(len=80),dimension(10):: memo
     
      integer :: number, Nwv, ittl, nthi, nphi, ntho, npho, n_memo, nmm, ithi,itho,ipho, idum,ipass,ith,m
      real :: sa,sb,sc,wv,cm1,cm2,xeq,gam,Cpol,Ccpl,Epol,CsCT,g
     
    ...
     
    !  if(ipass.eq.-999) then
    !     do ith = 1, ittl
    !        read(12,*)
    !     enddo
    !     return
    !  else
     
      do ithi = 1, abs(nthi)
        do ipho = 1, abs(npho)
          do itho = 1, abs(ntho)
            read(12,*)(ft(itho,ipho,ithi, m), m=1,16)
          enddo
        enddo
      enddo
     
      open(unit=10, file='/home/shadok/Bureau/splie3_call_mcfost.dat', access="append")
      write(10,*)'before entry splie3'
      write(10,*)"ft(1,1,1,1,m)",ft(1,1,1,:)
      write(10,*)"ft2(1,1,1,1,m)",ft2(1,1,1,:)
      close(10)
     
      do m = 1, 16
         call splie3(theo,phio,thei,ft(1,1,1,m),abs(ntho),abs(npho),abs(nthi),ft2(1,1,1,m)) 
      enddo
      return
     
    ...  
     
    end subroutine read_1_mat
    et le bout de code f77 correspondant:
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
          subroutine scamat5a
          include 'scamat_incl.f'   ! read imx: for max num for angles.
          dimension thi(imx),tho(imx),pho(imx), ! old: z(imx), p(imx), t(imx),
         &  ft(imx,imx,imx,16),                 ! the tabulated values.
         &  ft2(imx,imx,imx,16)                 ! the 2nd rank differential.
          character memo(10)*80
    c  
          common /agls/   thi,tho,pho, nthi,ntho,npho
          common /ftable/ ft,ft2    ! cf. /agls/ and /ftable/ are /ftable4_16/ in old version.
     
    ...
     
          if(ipass.eq.-999) then
            do ith = 1, ittl
              read(12,*)
            enddo
            return
          else
     
             do ith = 1, ittl
                read(12,*)(ft(ith,1,1,m), m=1,16)
             enddo
          endif
     
          open(unit=10, file='/home/shadok/Bureau/splie3_call_matsu.dat',
         *     access="append")
          write(10,*)'before entry splie3'
          write(10,*)"ft(1,1,1,1,m)",ft(1,1,1,:)
          write(10,*)"ft2(1,1,1,1,m)",ft2(1,1,1,:)
          close(10)
     
          do m = 1, 16
            call splie3(tho,pho,thi,ft(1,1,1,m),
         &              abs(ntho),abs(npho),abs(nthi),  ft2(1,1,1,m) ) 
          enddo
          return
     
    ...
     
          end
    Comme tu peux le voir j'imprime le tableau dans un fichier AVANT l'entrée dans la sous-routine et l'impression donne le même résultat:
    before entry splie3
    ft(1,1,1,1,m) 0.1879800 0.0000000E+00 0.0000000E+00 0.0000000E+00
    0.0000000E+00 1.000000 0.0000000E+00 0.0000000E+00 0.0000000E+00
    0.0000000E+00 1.000000 0.0000000E+00 0.0000000E+00 0.0000000E+00
    0.0000000E+00 1.000000
    ft2(1,1,1,1,m) 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00
    0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00
    0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.0000000E+00
    0.0000000E+00 0.0000000E+00
    Maintenant DANS la sous-routine splie3 les variables sont déclarées ainsi:

    code f90:
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    SUBROUTINE splie3(x0a,x1a,x2a, ya, L,m,n,y2a)
      implicit none
     
      Integer,PARAMETER:: NN=100
      INTEGER L,m,n
      real, dimension(L)::x0a
      real,dimension(m)::x1a
      real,dimension(n)::x2a
      real,dimension(L,m,n)::y2a,ya
     
      INTEGER i,j,k
      REAL, dimension(NN):: y2tmp,ytmp
     
      open(unit=10, file='/home/shadok/Bureau/splie3_call_mcfost.dat', access="append")
      do i=1,L
         do j=1,m
               write(10,*)'L:',i,'m:',j
               write(10,*)'ya : ',ya(L,m,:)
         end do
      end do
    ...
      close(10)
    ...
    END SUBROUTINE splie3
    code f77:
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
          SUBROUTINE splie3(x0a,x1a,x2a, ya, L,m,n,y2a)
          INTEGER L,m,n,NN
          REAL x0a(L), x1a(m),x2a(n),y2a(L,m,n),ya(L,m,n)
          PARAMETER (NN=100)
          INTEGER i,j,k
          REAL y2tmp(NN),ytmp(NN)
     
          write(*,*) "splie3ing..."
          open(unit=10, file='/home/shadok/Bureau/splie3_call_matsu.dat',
         *     access="append")
          do 15 i=1,L
             do 16 j=1,m
                write(10,*)'L : ',i, ' m : ',j
                write(10,*)'ya :',ya(L,m,:)
     16      continue
     15   continue
     
    ....
     
          close(10)
     
    ...
     
          return
          END
    Comme on peut le voir j'imprime la variable APRÈS l'entrée:

    pour le code f90 (je met que les première lignes car c'est long) j'obtiens:
    L: 1 m: 1
    ya : 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.1832600
    0.0000000E+00 0.0000000E+00 0.0000000E+00 0.1780300 0.0000000E+00
    L: 1 m: 2
    ya : 0.0000000E+00 0.0000000E+00 0.0000000E+00 0.1832600
    0.0000000E+00 0.0000000E+00 0.0000000E+00 0.1780300 0.0000000E+00
    etc...

    pour le code f77 j'obtient:

    L : 1 m : 1
    ya : 6.3878998E-02 6.3116997E-02 6.0954999E-02 5.7769001E-02 5.4200001E-02
    5.1155999E-02 4.9779002E-02 5.1339000E-02 5.7041999E-02
    L : 1 m : 2
    ya : 6.3878998E-02 6.3116997E-02 6.0954999E-02 5.7769001E-02 5.4200001E-02
    5.1155999E-02 4.9779002E-02 5.1339000E-02 5.7041999E-02
    Comme on peut le voir, ce sont TOUJOURS les même nombres mais ce ne sont pas les même entre les deux codes. Comment cela est-il possible ? Cela peut-il venir d'une différence dans l'initialisation des tableaux ? Mais dans ce cas, chaque chiffres serait différent alors non ?

    Merci de m'aider à démêler ce sac de noeuds

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Points : 1 346
    Points
    1 346
    Par défaut
    Déjà, en copiant des fonctions / routines F77 dans un module, tu modifies puisqu'il y aura automatique génération d'interfaces explicites. De là, il est possible que le passage de mat(1,1,i) qui en F77 correspond à passer un pointeur ne fonctionne plus.

  5. #5
    Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Août 2011
    Messages : 49
    Points : 50
    Points
    50
    Par défaut
    De là, il est possible que le passage de mat(1,1,i) qui en F77 correspond à passer un pointeur ne fonctionne plus.
    Ben en fait comme tu peux le voir dans les ajouts de mon précédent message, la transmission des arguments ne se fait pas via des pointeurs mais envoie directement les tableaux. Donc je vois pas ce que ça pourrait changer...


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [template] problème de passage de paramètres
    Par vinny_the_true dans le forum C++
    Réponses: 2
    Dernier message: 14/12/2005, 01h15
  2. [FLASH MX] Problème de passage de variable
    Par mandaillou dans le forum Flash
    Réponses: 2
    Dernier message: 15/11/2005, 10h22
  3. Réponses: 9
    Dernier message: 13/05/2005, 03h13
  4. problème de passage de paramêtre sous mozilla
    Par mat10000 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 27/09/2004, 10h48
  5. problème de passage de texte avec getvariable
    Par VincentB dans le forum Flash
    Réponses: 2
    Dernier message: 12/01/2004, 18h35

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