(Cette page est basée en partie sur une discussion apparue sur la liste Calcul en septembre 2008.)
Question
Est-il utile d'utiliser l'argument
stat
de l'instruction allocate
si c'est
seulement pour arrêter le programme lorsque stat
est non
nul ? (On ne discute donc pas ici le cas où l'on doit faire d'autres
traitements, pas seulement afficher un message d'erreur, après l'échec
du allocate
.)
Si l'instruction allocate
échoue sans argument
stat
, la norme Fortran prescrit l'arrêt du
programme.
Dans un programme séquentiel, la question revient donc à savoir si les messages affichés par les compilateurs au moment de l'arrêt du programme sont suffisamment informatifs : nom de la variable, nom du fichier source Fortran, nom de la procédure, numéro de ligne.
Dans un programme parallélisé avec MPI, en accord avec la norme
Fortran, si l'instruction allocate
échoue sans argument
stat
, alors le processus MPI qui exécute cette
instruction doit s'arrêter. Il n'est pas évident que les autres
processus MPI s'arrêtent. Si les autres processus MPI continuent, ils
peuvent consommer inutilement du CPU. Il peut donc être utile
de tester l'argument stat
d'allocate
pour
éventuellement appeler mpi_abort
.
La suite de cette page ne concerne que les programmes séquentiels.
Si les messages d'erreur affichés par les compilateurs sont
suffisamment informatifs alors on a tout intérêt à ne pas alourdir le
programme avec des tests de stat
.
Tests
Les tests sont faits avec le
programme test_allocate.f. En
exécutant ce programme, j'utilise l'instruction allocate
avec une taille de tableau trop grande. Pour faire ces tests en
débordant la taille de tableau autorisée mais sans déborder l'ensemble
de ma machine, je limite la mémoire virtuelle utilisable par le
processus :
ulimit -Sv 100000Le choix ci-dessus, environ 100 MiB, est un ordre de grandeur minimum pour que l'environnement d'exécution du programme en Fortran puisse se charger.
J'ai testé le programme avec 7 compilateurs : Intel Fortran, GNU Fortran, g95, NAG Fortran, PGI Fortran, XL Fortran (sur une machine IBM Power 4), FORTRAN90/SX (sur une machine NEC SX8). Pour chaque compilateur, j'ai compilé le programme une fois sans aucune option et une fois avec des options de débogage.
compiler | with debugging options | result |
---|---|---|
gfortran 5.4.0 | yes | Operating system error: Cannot allocate memory Allocation would exceed memory limit |
gfortran 5.4.0 | no | Operating system error: Cannot allocate memory Allocation would exceed memory limit |
ifort 17.0.1 | yes | forrtl: severe (41): insufficient virtual memory Image PC Routine Line Source libifcoremt.so.5 00002B9750E14573 for_allocate Unknown Unknown test_allocate 0000000000401592 MAIN__ 14 test_allocate.f |
ifort 17.0.1 | no | forrtl: severe (41): insufficient virtual memory |
NAG Fortran Compiler Release 6.0 | yes | Runtime Error: /home/guez/Test_allocate/test_allocate.f, line 14: Cannot allocate ALLOCATABLE variable - out of memory Program terminated by fatal error |
NAG Fortran Compiler Release 6.0 | no | Runtime Error: Cannot allocate ALLOCATABLE variable - out of memory Program terminated by fatal error |
pgfortran 16.9 | yes | 0: ALLOCATE: 108000000 bytes requested; not enough memory |
pgfortran 16.9 | no | 0: ALLOCATE: 108000000 bytes requested; not enough memory |
Avec les trois autres compilateurs, g95, XL Fortran et
FORTRAN90/SX, même sans option, lorsqu'il y a échec
du allocate
sans stat
, on a un message clair
avec localisation de l'erreur.
Conclusions
Il n'y a aucun cas où le programme continue après échec
du allocate
sans stat
. Tous les compilateurs
respectent en cela la norme.
Pour tous les compilateurs, avec ou sans options de débogage, le message d'erreur indique clairement que la cause du plantage est une demande de mémoire trop élevée.
Sans les options de débogage, plusieurs compilateurs ne donnent pas la localisation de l'erreur. Avec les options de débogage, deux compilateurs, gfortran et pgfortran, ne donnent pas la localisation de l'erreur. On peut donc imaginer que, dans certains contextes d'utilisation d'un programme, le bon choix soit de mettre l'argument stat pour certaines instructions allocate. Dans ce cas, il faut absolument afficher plus d'information en cas d'échec du allocate que n'en afficherait le compilateur en l'absence d'argument stat. À utiliser avec discernement pour ne pas alourdir significativement le programme.