[Fortran 77] Pb ecriture fichier : pseudo-NaN...

Pb ecriture fichier : pseudo-NaN... [Fortran 77] - Divers - Programmation

Marsh Posté le 26-01-2009 à 15:44:26    

Bonjour à tous,
 
Mes excuses d'avance pour ce post qui va etre un peu long, mais le problème que je rencontre n'est pas simple à expliquer.
 
Voila, je reprends en ce moment un ancien code en Fortran 77 pour le compléter avec de nouvelles fonctions. Avant cela, j'ai entrepris de le dépoussiérer un peu, et en particulier d'accorder un soin particulier aux declarations de variables, qui étaient toutes faites de manière implicite...
 
Le programme consiste à effectuer des calculs à l'intérieur d'une boucle principale, et d'écrire les résultats dans un fichier de sortie à chaque itération.
Au niveau de la console, le programme est "silencieux" , mis à part qques messages qui signalent que tout se passe bien.
 
A l'éxécution, TOUT SE PASSE EFFECTIVEMENT BIEN (les valeurs obtenues en fin de calcul sont vérifées par un moyen parallèle), j'insiste particulièrement sur ce point qui est important pour la suite.
OR, lorsque j'ouvre mon fichier de sortie j'obtiens ceci :
 
     N     OBJ TOT MAX     OBJ TOT MIN     OBJ TOT MOY    
     0     0.500300E+01    0.407003E-05    0.773183E+00
     1     NaN                  NaN                 NaN
     2     NaN                  NaN                 NaN
     3     NaN                  NaN                 NaN
     4     NaN                  NaN                 NaN
     5     NaN                  NaN                 NaN
 
Je n'ai mis que les 5 première itérations, mais ca continue comme ca jusqu'au bout.
 
La ou ca commence à devenir étrange, c'est que les valeurs affichées sont issues de variables "object_tot" qui est utilisée telle quelle dans les calculs aux itérations suivantes, donc CE NE SONT PAS DES "VRAIS" NaN, puisque le calcul aboutit normalement. Cela est de plus confirmé par le fait que j'écris un autre fichier de sortie ou la variable "object_tot" est utilisée , et la les valeurs sont correctes.
 
Malgré cela, j'ai entrepris, par des WRITE(*,*) successifs, de "pister" l'endroit ou se produti le problème jusqu'à une sous-routine un peu en amont. Mais la le plus étrange se produit :
Si, à l'intérieur de cette sous-routine, j'écris (pop_size etant la logical size de object_tot):
"DO i=1,pop_size
      WRITE(*,*) object_tot(i)
END DO "
Alors j'obtiens des valeurs correctes pour object_tot, ET LE FICHIER DE SORTIE AFFICHE LES BONNES VALEURS!!!!!
Autrement dit, un simple "write" de la variable qui pose problème corrige le problème, sans qu'aucune modificication portant sur le fonctionnement du code n'ait été réalisée...
 
Au final, tout se passe comme si, auniveau interne, les valeurs avaient la bonne valeur (puisque la calcul aboutit normalement), mais que des qu'il s'agit d'affichage (console ou fichier) alors le comportement devient chaotique. Vous comprendrez que cet effet "magique" rend le debuggage assez complexe.
 
Un dernier détail :
J'ai déjà rencontré ce problème avec une autre variable, qui, comme "object_tot", est un tableau déclaré avec la taille "pop_size_max" (fixée par une déclaration de type PARAMETER), alors que sa taille "reelle" au cours du calcul est pop_size. Je l'avais alors résolu en veillant à initialiser cette variable à 0 jusqu'à pop_size_max, et non jusqu'à pop_size, ce qui était le cas avant. Mais la meme vérification appliquée à ma variable "object_tot" n'a pas eu ici le meme effet.
 
DONC : je m'adresse à vous afin de recueillir vos ipressions sur le sujet, et en particulier, savoir si l'un d'entre vous avait déjà rencontré ce phénomène.

Reply

Marsh Posté le 26-01-2009 à 15:44:26   

Reply

Marsh Posté le 26-01-2009 à 15:44:58    

UPDATE :
 
en continuant à trifouiller un peu mon code, je n'ai fait que découvrir des choses toujours plus étranges :
 
D'abord, je me suis rendu compte qu'en commentant l'appel à la sous-routine incriminée, le problème disparaissait, signe que "quelquechose" était louche avec celle-ci
 
Du coup, j'ai successivement commenté et décommenté certaines lignes de la sous-procédure en question, pour me rendre compte que seule une ligne de code semblait etre à l'origine du problème, puisqu'en commentant cell-ci , tout fonctionnait.
Problème : cette ligne de code NE FAIT PAS intervenir la variable "object_tot" (meme indirectement)
 
Alors j'ai fait des WRITE(*,*) de toutes les variables intervenant dans cette sous-procédure, mais alors je retrouvai l'effet "guérisseur" du WRITE mentionné dans mon premier post.
 
Finalement, je me suis rendu compte que ce que j'affichais sur la console avec WRITE N'AVAIT AUCUNE IMPORTANCE. Afficher juste la chaine ' ' (un espace, donc...) suffit à régler le problème. Du coup je me suis dit que le problème venait du nombre de lignes de codes exécutées (je sais c absurde, mais bon...) et j'ai remplacé ce write par une ligne de code "bidon" (style "a=2" ), juste pour avoir une ligne de code supplémentaire, mais les NaN réapparaissent.
Conclusion : il faut que ce soit un WRITE
 
Voila, j'ai hate que quelqu'un m'explique ce qu'il se passe, parce que la j'en perds mon latin.

Reply

Marsh Posté le 26-01-2009 à 16:31:29    

Problème de description de format ?
Sinon, quel est ton compilateur ? Ça te fait la même chose avec un autre compilo ?

 

Et puis poste un peu le code d'écriture, notamment l'écriture ;)


Message édité par erulio le 26-01-2009 à 16:32:04
Reply

Marsh Posté le 26-01-2009 à 17:20:23    

J'utilise gfortran et je n'ai pas d'autre compilateur pour tester. Tu me conseilles lequel qui soit facile à installer (je suis sous Ubuntu 8.10)?
 
Sinon, voici une tentative d'outline très simplifié de mon code, avec les endroits et les variables qui concerne mon problème :  

Code :
  1. program XXXX
  2. implicit none
  3.  
  4.     integer n_step,pop_size,pop_size_max,n_best,n_worst
  5.     parameter (pop_size_max=10000)
  6.     double precision old_obj_tot(pop_size_max),new_obj_tot(pop_size_max),
  7.    *                      new_obj_tot_max,new_obj_tot_min,new_obj_tot_moy       
  8.     ..
  9.     ...
  10.    ....
  11.    ...
  12.    do i=1,n_step
  13.    ..
  14.    call kill_worst(pop_size_max,old_obj_tot,new_obj_tot,n_best,n_worst)
  15.    ..
  16.    ...
  17.    ....
  18.    ...
  19.    ..
  20.    call write_stat_object(new_obj_tot_max,new_obj_tot_min,new_obj_tot_moy)
  21.    .
  22.    end do
  23. ..
  24. end program


 
Donc ca c'est mon main (restreint aux instructions dont j'ai besoin pour mon exemple), ou la sous-routine kill_worst modifie new_obj_tot à partir des valeurs de old_obj_tot, n_best et n_worst, et la routine write_stat_object écrit des valeurs "statistiques" (type max,min et moyenne) issues de new_obj_tot.
 
kill_worst se présente comme ceci :  

Code :
  1. subroutine kill_worst_vlam(popul_size,old_object_tot,new_object_tot,num_best,num_worst)
  2. implicit none
  3. integer popul_size,num_best,num_worst,
  4. double precision old_object_tot(popul_size),new_object_tot(popul_size)
  5. c Variables locales
  6. integer i,j,ind_best,ind_worst
  7. write(99,*) ' '
  8. do i=1,num_best
  9. ..
  10. ...
  11. new_object_tot(ind_worst)=old_object_tot(ind_best)
  12. ...
  13. ..
  14. end do
  15. end


 
(NB : le WRITE(99,*) est le fameux write "magique" qui fait disparaitre les NaN de mes fichiers)
 
Quand à WRITE_STAT_OBJECT :

Code :
  1. subroutine write_stat_obj_vlam(object_tot_max,object_tot_min,object_tot_moy)
  2.       implicit none
  3. c     Variables I/O
  4.       double precision object_tot_max,object_tot_min,object_tot_moy
  5. .
  6. ..
  7. ...
  8.       write(10,102,advance='no') object_tot_max
  9.       write(10,102,advance='no') object_tot_min
  10.       write(10,103,advance='no') object_tot_moy
  11. ...
  12. ..
  13. 102  format(e12.6,4x)
  14. 103  format(e12.6,9x)


 
D'avance merci.


Message édité par bebekija le 26-01-2009 à 17:36:04
Reply

Marsh Posté le 26-01-2009 à 18:05:59    

Pour ma part, j'utilise indifféremment g95 ou gfortran.
Dans ta fonction d'écriture, t'as vérifié que les inputs étaient correctement lues ?
Sinon, je n'ai rien vu qui puisse faire apparaître un tel comportement (mais je ne suis pas expert fortran 77). Mais vérifie qu'il n'y a pas de problème d'interface (genre un double qui se transforme en real dans une fonction), c'est le genre de truc qui arrive quand tu mets à jour du vieux code.
 
Tu compiles avec des -W -Wall ? Sinon, fais-le :o

Reply

Marsh Posté le 29-01-2009 à 13:41:03    

J'utilise pas fortran donc je peux pas aider, mais je tiens à indiquer que Fortran n'est absolument pas un langage fonctionnel, le topic ne devrait donc pas être dans cette sous-cat, mais dans Divers.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 29-01-2009 à 13:41:54    

Masklinn > doléance notée. Je déplace ce topic.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed