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 :

Barre d'avancement boucle DO


Sujet :

Fortran

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut Barre d'avancement boucle DO
    Bonjour,

    Je cherche à coder en Fortran une barre de progression dans une boucle DO (équivalent à la waitbar Matlab, pour ceux qui connaissent).
    Pour ça j'utilise l'option ADVANCE = 'NO' pour écrire à l'écran ma progression (succession de '=' suivie du pourcentage de calcul effectué), et je réactualise la ligne à chaque itération en supprimant (écriture de backspace 'char(8)') la partie de la ligne concernée puis en écrivant à nouveau la progression (mise à jour par pas de 2%).

    Voici ce que j'ai codé, sous forme de sous-routine (je l'utilise plusieurs fois dans mon programme) et que j'appelle au début de chaque itération d'une boucle :
    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
     
    subroutine waitbar(iter,niter)
    	! affichage waitbar + pourcentage calcul
     
    	implicit none
    	integer*4 niter,iter,i
     
    	if (mod(100*(real(iter)/real(niter)),real(2)) == 0) then
    		do i=1,7
    		  write(*,'(a1)',advance='no') char(8)
    		enddo
     
    		write(*,'(a2)',advance='no') '=>'	
     
              write(*,'(a1,i3,a2)',advance='no')
         +      ' ',nint(100*(real(iter)/real(niter))),' %'
    	endif
     
    end
    Mon problème est que seule la dernière itération s'affiche (barre complète) et uniquement à la fin du calcul. Visiblement le problème viendrait de l'option ADVANCE='NO', puisque je n'ai aucun problème pour écrire sur des lignes successives le pourcentage effectué à chaque itération.

    Quelqu'un a-t-il déjà codé ce genre de chose, et pourrait m'éclairer ?
    Merci pour vos réponses.

    PS je compile avec Compaq Visual Fortran 6.5 sous Windows XP, ainsi que f90 sous unix et aucun ne marche.

  2. #2
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Thread ?
    Salut mec,

    essaie de voir si on peut faire des "threads" en fortran.
    En fait on a le même genre de problème si on veut faire une waitbar en java.
    Tu dis à ton programme de faire un premier processus (par exemple calculer une section iso X dans de la sismique multitrace) puis tu lui dis de mettre à jour ta wait bar, c'est un second processus.

    Fortran est bête, il traite un processus puis un autre. C'est pour ça que la wait bar ne se met à jour qu'une fois le premier processus réalisé.
    Pour que ta waitbar se mette à jour il faut que tu lances le premier processus dans un thread. Un thread est en quelque sorte un sous processus. On peut avoir pleins de threads dans un processus. Sauf qu'un thread à sa durée de vie propre, il commence quand on lui dit de commencer et n'attend pas qu'un processus avant lui soit terminé pour travailler.

    Il faudrait par exemple que tu mettes ta waitbar dans un thread, de cette façon elle tournerait en parallèle de ton processus principal et n'attendrait pas que le processus principal soit terminé pour faire son job.

    Regarde sur google les articles consacrés à la waitbar en java, je crois que dans developpez y a un exemple.

    On se voit ce midi à la cantoche

    A +

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    je ne pense que ça vienne de ça, puisque comme je l'ai indiqué plus haut, il n'y aucun problème pour lui faire afficher un pourcentage de progression à chaque itération sur des lignes successives (sans le paramètres ADVANCE).

  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
    Je ne sais pas pour le advance no. Je suspecte la combinaison du advance no avec les caractères backspace.

    Personnellement, j'utilise un progress bar comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    !
    !  Produit un progres bar en % de la forme
    !
    !  ----1----2----3----4----5----6----7--_
    !
          NbrEval = NbrEval + 1
          NbTics = 50.0 * real(NbrEval) / real(NbrEvalTot)
          do k = NbTicsPrec + 1, NbTics
             if (mod(k,5) == 0) then
                write(0,'(i0)',advance='no') k / 5
             else
                write(0,'(a)',advance='no') '-'
          enddo
          NbTicsPrec = NbTics

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Sylvain,

    je viens d'implémenter ton code, et j'ai toujours le même problème : la barre ne progresse pas en temps réel, et elle s'affiche complète une fois sorti de la boucle. Autrement dit elle fait tout l'inverse de ce que je souhaite.

    Je suppose que ça marche pour toi, donc a piori, mon code est correcte (on utilise tout deux les non-advancing I/O, donc il devrait fonctionner chez toi).

    Dans le cas du advance=yes la progression s'affiche bien à chaque itération, mais sur des lignes succéssives, ce que je souhaite éviter. Vraiment curieux...

    Je cherche sur internet si il éxiste des bugs connu d'incompatibilité boucle DO et advance=no... mais je ne trouve pas pour le moment.

  6. #6
    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
    Hmmm...

    2 pistes possibles selon moi :
    • Ta boucle est-elle suffisamment lente pour que tu vois l'effet ?
    • Il y a peut-être un effet de «buffering». La ligne n'est transmise qu'une fois complétée.


    Comme tu vois dans mon exemple, j'écris sur StdErr et non sur StdOut (Le unit 0 est StdErr sous Lahey avec lequel j'utilise ce code). Peut-être que ça affecte le buffering...

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Ta boucle est-elle suffisamment lente pour que tu vois l'effet ?
    Effectivement je me suis posé la question. Mais la réponse est oui, qui plus est je l'ai testé en debug, pas à pas, et rien ne s'affiche.

    Il y a peut-être un effet de «buffering». La ligne n'est transmise qu'une fois complétée.
    Je vais creuser la question : il semblerait que la ligne complète s'affiche dès l'instruction WRITE suivante, sans paramètre ADVANCE renseigné, ça confirme cette impression de "buffer".

    As-tu testé la partie de code que j'ai affiché plus haut (pour me rassurer) ?

  8. #8
    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
    Ça semble effectivement un problème de buffering.

    Baragouinnes-tu en anglais ? Si oui, va à l'adresse suivante :

    http://groups.google.com/group/comp....rch+this+group

  9. #9
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Effectivement, stdout (unit 6) est bufferisee, alors que stderr (unit 0) ne l'est pas (le numero des logical units n'est pas standardise, mais c'est l'usage le plus souvent observe). Une solution serait d'envoyer ta barre de progression sur stderr, mais ce n'est pas tres elegant.
    La solution que j'utilise est d'appeler une petite fonction C:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #include <stdio.h>
     
    void fortran_flush(void)
    {
       fflush(stdout);
    }
    que tu appeles simplement depuis ton code Fortran:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
          call fortran_flush()

  10. #10
    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
    Et ça marche ?

    Je croyais que le buffering se faisait au niveau de la librairie Fortran et non au niveau du OS... Ta solution semble indiquer au contraire que c'est au niveau du OS. Intéressant (sans arrière pensée !)

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Merc Sylvain pour le lien vers la discussion.
    En utilisant le symbole '$' dans le format d'écriture, ça marche parfaitement.
    (Attention symbole compatible uniquement avec le compilateur intel).

    J'ai aussi jeté un oeil à fflush (je m'y connais peu en C) et ça devrait effectivement fonctionner.

    Merci à tous les deux, mon problème est résolu.

  12. #12
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par Sylvain Bergeron
    Je croyais que le buffering se faisait au niveau de la librairie Fortran et non au niveau du OS... Ta solution semble indiquer au contraire que c'est au niveau du OS.
    Je ne suis pas sur, a vrai dire. Melanger Fortran et C suppose d'utiliser des ABI compatibles, donc souvent deux front-ends d'un meme compilateur. Du coup, c'est souvent la meme bibliotheque (par exemple glibc) qui se charge de l'I/O pour les deux langages -- c'est peut-etre pour cela que ca marche.

  13. #13
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Points : 476
    Points
    476
    Par défaut
    Citation Envoyé par Sylvain Bergeron Voir le message
    Je ne sais pas pour le advance no. Je suspecte la combinaison du advance no avec les caractères backspace.

    Personnellement, j'utilise un progress bar comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    !
    !  Produit un progres bar en % de la forme
    !
    !  ----1----2----3----4----5----6----7--_
    !
          NbrEval = NbrEval + 1
          NbTics = 50.0 * real(NbrEval) / real(NbrEvalTot)
          do k = NbTicsPrec + 1, NbTics
             if (mod(k,5) == 0) then
                write(0,'(i0)',advance='no') k / 5
             else
                write(0,'(a)',advance='no') '-'
          enddo
          NbTicsPrec = NbTics
    Bonjour,

    Je ressuscite ce post car j'aurais quelques questions en tant que débutant fortran

    Est ce que NbrEval est l'incrémentation?
    NbrEvalTot le nombre total de l'incrémentation
    Que représente alors NbTics et NbTicsPrec?

    Merci pour vos informations, j'aimerais aussi faire une barre de chargement pour fortran mais le lien vers un autre site dans le fil de la discussion de ce thread est mort (avec le temps..)
    OS : taff > Window 7 32bit - Home > Windows 7 64bit
    Matlab : taff > v2013b - Home > r2009a

  14. #14
    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
    La barre de progression fonctionne en pourcentage.

    Je dois faire 1 000 000 d'itération (NbrEvalTot), et je suis présentement rendu à l'itération 100 000 (NbrEval).

    Comme je veux afficher ma barre sur la console, et qu'il est alors préférable de ne pas dépasser la colonne 80 (héritée des punched card et des anciens écrans textes), j'avais donc décidé de faire une progression sur 50 caractères, chacun représentant donc 2 % de progression. Ainsi, je calcule le nombre de 50ième (NbTics) atteint : 50 * NbrEval / NbrEvalTot.

    Finalement, comme je ne fais qu'allonger un début de barre déjà affiché, je dois donc seulement écrire le nombre de caractères requis après ceux déjà affichés (NbTicsPrec).

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Points : 476
    Points
    476
    Par défaut
    Merci pour votre réponse rapide,

    Si je comprends bien, ce petit code est à insérer dans directement dans la boucle itérative pour laquelle on veut avoir un barre de chargement.

    Dans ce cas, NbrEval est directement la variable d'incrémentation.
    et NbTics sera calculé à chaque itération.

    Mais alors il fait la boucle do k [...] autant de fois que de nombre d'itération et devrait afficher soit un entier de la division par 5 soit un tiret ?.. je dois me tromper..

    Comment évaluez vous NbTicsPrec au début? à 0 ?

    merci
    OS : taff > Window 7 32bit - Home > Windows 7 64bit
    Matlab : taff > v2013b - Home > r2009a

  16. #16
    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
    Citation Envoyé par Newenda Voir le message
    Si je comprends bien, ce petit code est à insérer dans directement dans la boucle itérative pour laquelle on veut avoir un barre de chargement.
    Oui, et préférablement à la fin puisqu'elle calcule les % complétés.

    Citation Envoyé par Newenda Voir le message
    Dans ce cas, NbrEval est directement la variable d'incrémentation.
    et NbTics sera calculé à chaque itération.
    Oui, oui.

    Citation Envoyé par Newenda Voir le message
    Mais alors il fait la boucle do k [...] autant de fois que de nombre d'itération et devrait afficher soit un entier de la division par 5 soit un tiret ?.. je dois me tromper.
    La boucle part du nombre de symbole déjà affiché + 1, et va jusqu'à NbTics. Elle permet donc d'afficher les symboles additionnels pour atteindre NbTics symboles affichés. La boucle sert à couvrir les cas où tu avancerais de plus que 2% à chaque itération (dans ce cas, il faut afficher plus qu'un seul nouveau symbole). La division par 5 et le modulo 5 permettent d'afficher 1, 2, 3, ... quand NbTics (ou k) vaut 5, 10, 15, ... cinquantième, soit 10%, 20%,... Autrement, un tiret est affiché. Le résultat est donc une suite de tiret entrecoupée des 10% atteints: ----1----2----3--...

    Citation Envoyé par Newenda Voir le message
    Comment évaluez vous NbTicsPrec au début? à 0 ?
    Oui, oui (puisqu'il n'y a pas de symboles affichés au début).

  17. #17
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Points : 476
    Points
    476
    Par défaut
    Merci pour toutes ces remarques.

    Je me permets alors de placer ici votre code dans un programme opérationnel pour les futurs visiteurs :

    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
    program loop
     
    implicit none
    integer(kind=4)::i,k,NbTics,NbrEval,NbrEvalTot,NbTicsPrec
     
    NbrEvalTot=10
    NbTicsPrec=0
    NbrEval=0
     
    do i = 1, NbrEvalTot
    call sleep(1)
     
      NbrEval = NbrEval + 1
      NbTics = 50.0 * real(NbrEval) / real(NbrEvalTot)
      do k = NbTicsPrec + 1, NbTics
      if (mod(k,5) == 0) then
      write(0,'(i0)',advance='no') k / 5
      else
      write(0,'(a)',advance='no') '-'
      end if
      enddo
      NbTicsPrec = NbTics
     
    enddo
     
    write (*,*) 
     
    end
    OS : taff > Window 7 32bit - Home > Windows 7 64bit
    Matlab : taff > v2013b - Home > r2009a

  18. #18
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Points : 476
    Points
    476
    Par défaut
    Par contre j'ai voulu le subroutiner mais là problème..

    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
    program loop
     
    implicit none
    integer(kind=4)::i
     
     
    do i = 1, 10
    call sleep(1)
    call progress(i)
    enddo
     
    write (*,*)
     
    end
     
    subroutine progress(NbrEval)
     
    implicit none
    integer(kind=4) :: k,NbTics,NbrEvalTot,NbTicsPrec,NbrEval
    NbTicsPrec=0
    NbrEvalTot=10 
     
    NbrEval = NbrEval + 1
    NbTics = 50.0 * real(NbrEval) / real(NbrEvalTot)
    do k = NbTicsPrec + 1, NbTics
    if (mod(k,5) == 0) then
    write(0,'(i0)',advance='no') k / 5
    else
    write(0,'(a)',advance='no') '-'
    end if
    enddo
    NbTicsPrec = NbTics
     
    return
    end
    donne ..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./loop2----1----2----1----2----3----4----1----2----3----4----5----6----1----2----3----4----5----6----7----8----1----2----3----4----5----6----7----8----9----10
    Voyez vous le problème?
    OS : taff > Window 7 32bit - Home > Windows 7 64bit
    Matlab : taff > v2013b - Home > r2009a

  19. #19
    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
    Le problème est que NbTicsPrec perd sa valeur et est remis à zéro d'un appel à l'autre. Je ne suis pas certain de la syntaxe et je n'ai pas accès présentement à un compilateur Fortran, mais tu devrais déclarer NbTicsPrec par « integer, save :: NbTicsPrec = 0 » et enlever la ligne NbTicsPrec = 0.

  20. #20
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 002
    Points : 476
    Points
    476
    Par défaut
    Super merci, tout marche parfaitement.
    OS : taff > Window 7 32bit - Home > Windows 7 64bit
    Matlab : taff > v2013b - Home > r2009a

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

Discussions similaires

  1. Afficher une barre d'avancement dans une fenêtre
    Par Olivier.p dans le forum VBScript
    Réponses: 8
    Dernier message: 05/08/2010, 17h01
  2. Creer une barre d'avancement avec FORMS
    Par bm_oracliste dans le forum Forms
    Réponses: 3
    Dernier message: 19/11/2007, 13h47
  3. Barre d'avancement d'une tâche
    Par Wolfgang31 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 05/09/2007, 18h05
  4. barre d'avancement pour la lecture d'un mp3 : Pb onChange!
    Par avogadro dans le forum C++Builder
    Réponses: 3
    Dernier message: 25/12/2006, 20h40
  5. barre d'avancement html ?
    Par djnellio dans le forum Langage
    Réponses: 4
    Dernier message: 11/04/2006, 11h58

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