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 :

Lecture unformatted dans module


Sujet :

Fortran

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 4
    Par défaut Lecture unformatted dans module
    Bonjour, quelqu'un aurait-il une idée ?

    J'explique mon souci : j'ai créé une subroutine qui lie des données binaire d'un fichier. Lorsqu'elle est placée dans le programme principal (dans le contains), tout fonctionne sans soucis.
    Cependant lorsqu'on place cette subroutine dans un module externe (programmation 'modulaire'), l'executable ouvre le fichier sans soucis, mais plante au premier read. L'erreur est la suivante "forrtl: severe (39): error during read, unit 11, file xxxx/yyy/".

    Techniquement, cela devrait fonctionner. Il n'y a pas d'erreurs de compilations. Les implicit none sont OK, et il n'y a pas de variables communes.

    Voici le code :
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
     
    PROGRAM prog
    USE cv_flv3d
    IMPLICIT NONE
    !! ******************* DEBUT ENTETE FICHIER ********************
    !!
    !! _NOM         :  prog
    !! _DESCRIPTION :  test des modules
    !! _HISTORIQUE  :  Version 1.0
    !! _DATE        :  08 - 07 -2008
    !! ******************* FIN ENTETE FICHIER **********************
     
    !! DECLARATIONS
    CHARACTER(LEN=200)                            :: fich    ! Nom du fichier
    REAL(KIND=8), DIMENSION(:,:,:,:), ALLOCATABLE :: tab     ! Table des données
    INTEGER(KIND=8)                               :: nbloc  &! Nombre de blocs
                                                  &, imax   &! indice i max
                                                  &, jmax   &! indice j max
                                                  &, kmax    ! indice k max
    INTEGER :: tmp,tmp2
     
    WRITE(*,'(a17)') "Nom du fichier : "
    READ (*,*)       fich
     
    CALL rd_dimflow(TRIM(fich),nbloc,imax,jmax,kmax)
     
    WRITE(*,*) 'nbloc', nbloc
    WRITE(*,*) 'imax' , imax
    WRITE(*,*) 'jmax' , jmax
    WRITE(*,*) 'kmax' , kmax
     
     
    ALLOCATE(tab(1:imax,1:jmax,1:kmax,1:nbloc))
    CALL rd_flow(TRIM(fich),tab)
     
    !WRITE(*,*) tab
     
    STOP
    END PROGRAM prog
     
    Voici le module :
    MODULE cv_flv3d
    IMPLICIT NONE 
    !! ****************** MODULE cv_flv3d ***********************
    !! _NOM         : cv_flv3d 
    !! _DESCRIPTION : Convertions et lectures des fichiers 
    !!                flow type v3d
    !! _CONTEXTE    :
    !! _REMARQUES   :
    !! _VOIR        :
    !! ******************* MODULE cv_flv3d **********************
     
     
    CONTAINS
     
    SUBROUTINE rd_dimflow(fich,nbloc,imax,jmax,kmax)
       IMPLICIT NONE
       !! DECLARATIONS
       CHARACTER(LEN=*), INTENT (IN)    :: fich    ! Nom du fichier
       INTEGER(KIND=8) , INTENT (INOUT) :: nbloc  &! Nombre de blocs
                                        &, imax   &! indice i max
                                        &, jmax   &! indice j max
                                        &, kmax    ! indice k max
       INTEGER(KIND=8)                  :: tmp    &! variable inutilisee
                                        &, tmp2    ! variable inutilisee
       CHARACTER(LEN=20)                :: chaine  ! chaine inutilisee
     
     
       !! INSTRUCTIONS
       OPEN(UNIT=14,FILE=fich,FORM='unformatted',STATUS='old')
          READ(14) 
          nbloc = 5  ! ro rou rov row roe
          READ(14) chaine
          READ(14) tmp,tmp2,imax,jmax,kmax
       CLOSE(14)
     
       RETURN
    END SUBROUTINE rd_dimflow
     
     
    SUBROUTINE rd_flow(fich,tab)
       IMPLICIT NONE
     
       !! DECLARATIONS
       CHARACTER(LEN=*),                 INTENT (IN)    :: fich    ! Nom du fichier
       REAL(KIND=8), DIMENSION(:,:,:,:), INTENT (INOUT) :: tab     ! Tableau des valeurs
       INTEGER(KIND=8)                                  :: nbloc  &! Nombre de blocs
                                                        &, imax   &! indice i max
                                                        &, jmax   &! indice j max
                                                        &, kmax   &! indice k max
                                                        &, i,j,k,l&! variable de bouclage
                                                        &, tmp    &! variable inutilisee
                                                        &, tmp2    ! variable inutilisee
       !! INSTRUCTIONS
       OPEN(UNIT=11,FILE=fich,FORM='unformatted',STATUS='old')
          READ(11) nbloc
          nbloc = 5
          DO l=1,nbloc
             READ(11)                           ! Le nom du bloc ex : "va ro"
             READ(11) tmp,tmp2,imax,jmax,kmax   ! nrec,ndom,imax,jmax,kmax
             READ(11) (((tab(i,j,k,l),i=1,imax),j=1,jmax),k=1,kmax)
          END DO
       CLOSE(11)
     
       RETURN
    END SUBROUTINE rd_flow
     
    END MODULE cv_flv3d
    Merci d'avance !

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    489
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 489
    Par défaut
    Bonjour,

    Sans avoir trop regardé ton programme, le message d'erreur error during read, unit 11, file xxxx/yyy/ laisse à penser qu'il y a un problème au niveau du nom même du fichier ("xxxx/yyy/" ? Le "/" final ne concorde pas).

    Pour t'assurer que le problème ne vient pas de là, tu devrait ajouter des tests de bon déroulement des opérations lors de tes ouvertures/lectures via l'argument IOSTAT (de type 'integer').
    Par exemple pour s'assurer que l'ouverture du fichier se passe bien:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    OPEN(UNIT=11,FILE=fich,FORM='unformatted',STATUS='old',IOSTAT=ok)
    if (ok.ne.0) then
      write(*,*) "Erreur... Echec lors de l ouverture du fichier ",trim(fich)
    endif
    Et pour s'assurer qu'une lecture s'est bien passée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    READ(UNIT=11,IOSTAT=ok) nbloc
    if (ok.ne.0) then
      write(*,*) "Erreur... Echec lors de la lecture de nbloc "
    endif
    Bonne continuation.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 4
    Par défaut
    Merci beaucoup pour cette réponse,
    Le "/xxxx/yyy/" ne correspond en fait à rien, j'ai simplement mis cela à la place du nom du fichier réel, il ne faut donc pas en tenir compte.

    En fait, j'ai déjà fait tous ces tests (IOSTAT, messages, ...). Il n'y a pas d'erreurs lors de l'ouverture du fichier. Mais il y en a une lors de la première lecture (dans le fichier binaire la première lecture correpond à un entier et je lis un entier, donc par d'erreur de ce point de vue)

    Je resitue le problème : la subroutine fonctionne très bien lorsqu'elle est placée dans le fichier du programme principal (dans la partie contains). Cependant elle ne fonctionne plus (ouverture fichier OK, première lecture PLANTAGE) lorsqu'elle se situe dans un fichier de module (dans le fichier du programme principal il y a bien entendu USE nom_module)

    Je continue à chercher,

    J'ai deux pistes : soit cela vient du fait que le fichier est binaire (mais cela m'étonnerai), soit parce-qu'il n'y a pas de lien de taille dynamique entre le programme et le module (REAL(KIND=8), DIMENSION(:,:,:,, INTENT (INOUT) au lieu de REAL(KIND=8), DIMENSION(A:B,C,E:F,G:H), INTENT (INOUT)) ....

  4. #4
    Membre émérite Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Par défaut
    si c'était un problème de taille de tableau tu aurais les erreur suivantes:
    -tableau trop petit : Segmentation fault...
    -tableau trop grand: il te dirai qu'il a déjà atteind la fin du fichier...

    quel est ton compilateur au fait? as-tu été cherché ce qu'était l'erreur "forrtl: severe (39): error during read, unit 11" pour ce compilateur?

    si tu utilise gfortran ou g95, rajoute l'option -fbound-check à l'édition de liens, des fois que... ainsi que les option de compilation -Wall et traite tous les messages de warning que tu reçois...

    essaye de faire une déclaration de module à l'aide d'un bloc interface au lieu du contains

    De plus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    READ(11) nbloc
          nbloc = 5
    je vois pas l'intéret de ces deux lignes...

    est-ce que chacun de tes "bloc" ont des taille i,j,k différentes???

    as-tu essayer en déclarant ton tableau non pas en allocatble mais de taille fixe, juste pour voir si cela marche?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 4
    Par défaut
    Effectivement le message ne correspond pas à un problème de taille.

    Le message d'erreur indiqué provient du compilateur ifort (intel). J'ai également testé avec d'autre compilateurs : g95 (sous linux et macos x au cas où cela proviendrai de la machine) et sxf90 (un compilateur pour supercalculateur) mais toujours le même problème au même niveau.

    Je n'ai pas encore trouvé à quoi correspondait le message d'erreur ..severe(39)... (affaire à suivre)

    Concernant, READ(11) nbloc suivit de nbloc = 5 :
    C'est vrai que cela n'a pas de sens pour le lecteur, de prime abord. En fait pour expliquer, je lis un fichier de données avec différentes variables associées à un maillage (imax jmax et kmax sont les mêmes, il est possible qu'il soit différents lorsau'il y a plusieurs maillage, mais c'est une autre affaire ...). Chacune des variables est inscrite dans le fichier en 'bloc'. Or dans ce fichier il y a 10 variables (par exemple) et seules les 5 premières m'intéresse. Le READ(11) nbloc, peut être remplacé par READ(11) , mais je l'ai laissé pour vérifier la lecture.

    Qu'entends-tu par :
    essaye de faire une déclaration de module à l'aide d'un bloc interface au lieu du contains
    ?

    Merci encore pour votre aide

  6. #6
    Membre émérite Avatar de genteur slayer
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2002
    Messages : 710
    Par défaut
    en gros, je pense que cela ne change pas des masse: tu transforme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    module toto
     
    contains
     
    subroutine titi(params...)
      implicit none
      type,intent() :: params
      ....
      <code>
      ....
    end subroutine titi
    end module toto
    par

    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
     
    module toto
     
      interface
     
        subroutine titi(params...)
          implicit none
          type,intent() :: params
        end subroutine titi
     
      end interface
     
    end module toto
     
    subroutine titi(params...)
      implicit none
      type,intent() :: params
      ....
      <code>
      ....
    end subroutine titi
    cela permet une meilleur description explicit surtout si dans un même module il y a plusieurs fonction/subroutine qui peuvent s'appeler les unes les autres...

    sinon, autre chose à regarder:

    écris-tu ton fichier binaire de manière séquentiel,direct... etc...?

    dans le cas d'un sequentiel: tu peux enrichir ta lecture:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    open(unit= 15,          &
            File="toto.dat", &
            FORM="unformatted",&
            ACCESS="sequential",&
            ACTION="read",        &
            POSITION="rewind",  &
            IOSTAT=ios )
    if (ios/=0) stop "problème d'ouverture"
    READ(unit=15,IOSTAT=ios) ......
    do while (ios==0)
      READ(unit=15,IOSTAT=ios) ......
    end do
    close(unit=15)
    l'avantage de lire comme cela et non pas sous la forme "lit un tableau complet" est que tu peux récupéré le code d'érreur ios au cours de la lecture. le ios du open donne les erreur d'ouverture, le ios dans le read donne les erreur de lecture.
    De plus spécifie bien le maximum d'option dans le open... si tu ne le fait pas, cela se fait de manière automatique, et des surprises peuvent arriver quand on change de machine ou de compilo...

    dans le dernier petit bout de code, évidement, le ios change de valeur quand on arrive à la fin du fichier et donc la boucle s'arrête efectivement

Discussions similaires

  1. Lecture Arrière dans un TMediaPlayer
    Par kurul1 dans le forum C++Builder
    Réponses: 1
    Dernier message: 28/04/2006, 12h01
  2. Lecture choix dans liste deroulante
    Par angelevil dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 15/03/2006, 16h20
  3. ouverture/lecture/ecriture dans un fichier en mode binaire
    Par dirty_boy dans le forum Débuter
    Réponses: 2
    Dernier message: 15/03/2006, 08h38
  4. [PERL] Problème lecture/écriture dans un fichier
    Par LE NEINDRE dans le forum Langage
    Réponses: 4
    Dernier message: 17/08/2005, 13h15
  5. [JDBC]lecture/ecriture dans une base de donnée
    Par tarik75 dans le forum JDBC
    Réponses: 7
    Dernier message: 30/06/2005, 12h42

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