Jean Zay : mesure de la mémoire et les outils idrmem

Avant propos

Sur Jean Zay, la limite mémoire s'applique sur la mémoire physique réellement utilisée par votre programme. Par conséquent, nous mettons à votre disposition les outils idrmem permettant de connaitre la consommation maximale de mémoire physique lors de l'exécution de vos programmes.

Deux outils idrmem existent : l'un destiné aux codes MPI (bibliothèque MPI idrmem) et l'autre destiné aux codes OpenMP ou séquentiels (commande idrmem). Ils retournent l'information concernant l'utilisation de la mémoire en fin d'exécution du programme.

Les divers outils idrmem sont disponibles via la commande module :

$ module avail idrmem
 
------- /gpfslocalsup/pub/modules-idris/modulefiles/linux-rhel7-x86_64 -------
idrmem/1.4        idrmem/1.4-mpi

Utilisation avec les codes MPI

Dans ce cas, c'est la bibliothèque MPI idrmem qui permet d'afficher les consommations maximales de la mémoire virtuelle et de la mémoire physique utilisée par un code MPI pendant la durée de son exécution. Notez que l'affichage a lieu au moment où le programme exécute l'une des instructions MPI_Finalize ou MPI_Abort.

Il est indispensable de charger le module correspondant pour compiler votre programme MPI :

$ module load idrmem/1.4-mpi
$ mpiifort main.f90 -o main -lidrmem

Par contre, aucun changement n'est nécessaire dans le script de soumission (aucun module à charger, ni commande à exécuter).

En fin d’exécution, on obtient sur la sortie standard le temps elapsed, le maximum de consommation de mémoire virtuelle (VMSizeMax), le maximum de consommation de mémoire physique (RSSMax) et le maximum de consommation de la pile (StackMax), ainsi que les rangs des processus MPI sur lesquels ces maximums sont atteints :

IdrisMemMPI v1.4 : elapsed = 0.32 s, VMSizeMax = 497 mB on rank 1, RSSMax = 28 mB on rank 0, StackMax = 408 kB on rank 1

Si vous souhaitez afficher la consommation courante à un moment précis, il suffit d'insérer dans votre code un appel à la routine idr_print_mem fournie avec la bibliothèque MPI idrmem :

  CALL idr_print_mem()

Problèmes connus de la bibliothèque MPI idrmem

  • En mode MPMD, il est nécessaire que l'ensemble des codes soit compilé avec la bibliothèque MPI idrmem.
  • Si, pour une raison quelconque, le programme n'exécute ni l'instruction MPI_Finalize, ni l'instruction MPI_Abort alors aucune information n'est retournée.

Utilisation avec les codes OpenMP ou séquentiel

Dans ce cas, c'est la commande idrmem qui permet d'afficher, au moment où le programme s'arrête, les consommations maximales de mémoire physique et virtuelle.

Pour l'utiliser avec un code séquentiel ou OpenMP, il suffit de charger le module correspondant et d'utiliser la commande idrmem pour exécuter votre programme :

$ module load idrmem/1.4
$ idrmem ./executable_seq

Notez que la commande idrmem peut aussi être utilisée avec les codes MPI même si, naturellement, la bibliothèque MPI idrmem est à privilégier. Vous devez alors faire ceci :

$ module load idrmem/1.4
$ srun idrmem ./executable_mpi

La commande idrmem affiche dans la sortie standard, le temps elapsed, le maximum de consommation de mémoire virtuelle (VMSizeMax), le maximum de consommation de mémoire physique (RSSMax) et le maximum de consommation de la pile (StackMax) :

IdrisMem v1.4 : elapsed = 24.61 s, VMSizeMax = 1257 MB, RSSMax = 791 MB, StackMax = 92 kB

Pour effectuer des mesures en cours d'exécution, nous vous proposons la procédure procstat à insérer dans votre code.

Problèmes connus de la commande idrmem

  • ne fonctionne pas avec une commande qui est un alias;
  • ne donne pas les bons résultats si l'exécutable est un script ou un exécutable qui lance d'autres exécutables;
  • si la limite en temps d'exécution (#SBATCH –time=HH:MM:SS) est atteinte, il n'y aura pas d'affichage.
  • ne s’arrête pas immédiatement lors d'un appel à MPI_Abort, utilisez alors la bibliothèque MPI idrmem pour codes MPI;

Procédure procstat

Si vous souhaitez pouvoir afficher le maximum de consommation mémoire à n'importe quel moment, voici une procédure fortran que vous pouvez ajouter dans votre code :

subroutine_procstat
subroutine procstat()
  character(len=128) :: key, mot1, mot2
  integer :: ios, iter, My_unit
  ! Ouverture du fichier
  OPEN ( NEWUNIT = My_unit ,    FILE     = '/proc/self/status', &
         FORM   = 'formatted' , ACCESS   = 'sequential',        &
         ACTION = 'read' ,      POSITION = 'rewind' ,&          
         IOSTAT = ios )                                    
  IF ( ios /= 0 ) stop " Probleme a l'ouverture "
 
  ! Lecture du nom de l'executable (pour verification)
  READ (UNIT =My_unit , FMT=*, IOSTAT = ios ) key, mot1
  DO WHILE (trim(key) /= "VmPeak:")
    READ (UNIT =My_unit , FMT=*, IOSTAT = ios ) key, mot1,mot2
  END DO
  print *, "procstat : VMSizeMax = ", trim(mot1), trim(mot2)
  DO WHILE (trim(key) /= "VmHWM:")
    READ (UNIT =My_unit , FMT=*, IOSTAT = ios ) key, mot1, mot2
  END DO
  print *, "procstat : RSSMax = ", trim(mot1), trim(mot2)
  DO WHILE (trim(key) /= "VmStk:")
    READ (UNIT =My_unit , FMT=*, IOSTAT = ios ) key, mot1, mot2
  END DO
  print *, "procstat : StackMax = ", trim(mot1), trim(mot2)
  CLOSE ( UNIT =My_unit )
end subroutine procstat

Ensuite un call procstat() dans votre code provoquera l'affichage sur la sortie standard du maximum de la consommation de mémoire virtuelle, de mémoire physique et de la pile depuis le lancement du programme.