Jean Zay : options principales des compilateurs Intel Fortran et C/C++

Nous ne détaillons ici qu'une partie des options proposées par les compilateurs Intel. Nous vous invitons à consulter les manuels d' ifort et d' icc disponibles sur Jean Zay (commandes man ifort et man icc) pour des informations détaillées sur toutes les options disponibles.

Options d'optimisation des compilateurs Fortran et C/C++

C'est l'option -O (la lettre o majuscule) qui permet de gérer l'optimisation d'un code. Il est possible d'indiquer le niveau d'optimisation désiré en adjoignant une valeur entière (0, 1, 2 ou 3). L'option -O0 (tiret o majuscule zéro) permet d'inhiber toute optimisation faite par le compilateur. L'écriture -O (tiret o majuscule seul) est équivalente à -O2; c'est par ailleurs le niveau d'optimisation par défaut.

Attention : à partir du niveau 3, la sémantique du programme peut être modifiée. Par exemple : (2.*3.1)*4.2 peut être interprété comme 2.*(3.1*4.2). Soyez donc très vigilants quant aux résultats de vos calculs : il est nécessaire, à partir de-O3, de valider les résultats de votre modèle en les comparant avec une exécution réalisée avec une optimisation modérée ou, délibérément, sans aucune optimisation.

Options d'optimisation Commentaires
-O0 Aucune optimisation effectuée.
-O1 Quelques optimisations permettent d'accélérer modérément les calculs.
-O2 ou -O (défaut) Niveau d'optimisation incluant la vectorisation, l'inlining, le déroulement de boucle, l'optimisation inter-procédurale au sein de chaque fichier source, etc.
-O3 Optimisations plus agressives qu'en -O2 avec le prefetching, les transformations de boucle, la duplication de code, …
-O3 -xHost Permet d'activer la vectorisation AVX2 et partiellement AVX512. Elle déclenche une analyse plus exhaustive des dépendances de données et peut donc accroître le temps de compilation.
-O3 -xHost -qopt-zmm-usage=high Permet d'activer totalement la vectorisation AVX512. Elle déclenche une analyse plus exhaustive des dépendances de données et peut donc accroître le temps de compilation.

Il est possible que votre code ne donne pas les mêmes résultats en -O3 qu'en -O2. Vous pouvez alors obtenir un niveau d'optimisation intermédiaire en ajoutant l'option -fp-model suivie d'un mot clé (par exemple -O3 -fp-model precise).

Options d'optimisation Commentaires
-O3 -fp-model strict Les optimisations effectuées assurent la précision des calculs sur les nombres en virgule flottante (niveau le plus strict). De plus, la gestion des exceptions est activée.
-O3 -fp-model strict -fp-model no-except Comme précédemment, mais sans la gestion des exceptions.
-O3 -fp-model precise Assure la précision des calculs sur les nombres en virgule flottante. Il n'y a pas de gestion des exceptions.
-O3 -fp-model precise -fp-model except Comme précédemment, mais avec la gestion des exceptions.
-O3 -fp-model fast=1 ou -O3 -fp-model fast Autorise des optimisations plus agressives pouvant altérer la précision des calculs sur les nombres en virgule flottante. Peut donner de meilleures performances, mais ne peut pas être combinée avec la gestion des exceptions (-fp-model except).
-O3 -fp-model fast=2 Le code peut être encore plus rapide et moins précis qu'avec -fp-model fast=1. Ne peut pas être combinée avec la gestion des exceptions (-fp-model except).

Remarque : En l'état actuel, l'option -fast est équivalente aux options : -ipo -O3 -no-prec-div -xHost -static. Pour obtenir un exécutable, il est nécessaire d'enlever l'option -static. Comme nous vous déconseillons de spécifier l'option -fast de façon isolée, utilisez plutôt : -ipo -O3 -no-prec-div -xHost.

Options mémoire pour les compilateurs Fortran et C/C++

Options mémoire Commentaires
-auto Les variables locales déclarées au sein d'une unité de programme sans l'attribut SAVE et non initialisées seront allouées à l'entrée de cette unité dans la pile d'exécution ou stack. Cette option permet alors de réduire la taille de l'exécutable (zones statiques DATA et BSS). Les variables locales doivent être valorisées explicitement sinon elles ont une valeur indéfinie (l'option ''-ftrapuv'' permet de détecter les variables non initialisées). L'option par défaut est -auto-scalar (seules les variables locales scalaires sont allouées dans le stack. L'option inverse est -save : toutes les variables locales héritent de l'attribut SAVE, elles sont allouées statiquement dans la zone BSS et initialisées implicitement à une valeur nulle.
-mcmodel=small L'espace mémoire réservé au code (zone TXT) et aux données (zone DATA et BSS) est alors limité à 2Go. Cette valeur est suffisante dans la plupart des cas et le code présente alors les meilleures performances.
-mcmodel=medium -shared-intel Dans ce cas, seul l'espace mémoire réservé au code (zone TXT) est limité à 2Go; il n'y a aucune restriction pour les données. Les performances du code peuvent être légèrement dégradées. Cette option est nécessaire si vous avez des données statiques et globales (tableaux statiques p.ex.) dont la taille dépasse 2Go. Notez que vous devez aussi spécifier l'option -shared-intel.
-mcmodel=large -shared-intel Il n'y a alors aucune restriction concernant l'espace mémoire réservé au code ou aux données. Les performances du code peuvent être légèrement dégradées. Notez que vous devez aussi spécifier l'option -shared-intel.

Remarque : les options -mcmodel=medium -shared-intel doivent être ajoutées à la compilation et à l'édition de liens si, à l'édition de lien, vous obtenez des messages du type :

relocation truncated to fit: R_X86_64_PC32 against symbol ...

Ces messages peuvent apparaître lorsque l'on utilise des gros tableaux statiques, par exemple.

Options de diagnostic des compilateurs Fortran et C/C++

Lors de la compilation, des options permettent de récupérer certains messages de diagnostic sur la sortie standard ou dans un fichier :

Options de listage Commentaires
-qopt-report=[n] Génère, sur la sortie standard, un rapport des transformations liées à l'optimisation (inlining, vectorisation, déroulement de boucle, etc…). n est optionnel et peut valoir 0, 1, 2 ou 3 (par défaut 2) . Plus n est grand, plus le rapport est détaillé.
-opt-report-file=filename Génère un rapport dans le fichier spécifié par filename. Dans ce cas, il n'y a plus besoin de spécifier l'option -qopt-report.
-qopt-report-phase=phase -qopt-report Combinaison de deux options permettant de générer un rapport des optimisations effectuées par l'élément phase de l'optimiseur. phase peut valoir :
ipo : Interprocedural Optimizer phase;
hlo : High Level Optimizer phase;
hpo : High Performance Optimizer phase;
ilo : Intermediate Language Scalar Optimizer phase;
pgo : Profile Guided Optimization phase;
openmp: OpenMP;
par : Auto-parallélisation;
vec : Vectorisation;
all : All optimizer phases.

Exemples :

$ ifort -O3 -qopt-report=3 prog.f90
$ ifort -O3 -qopt-report-file=my_report_file prog.f90
$ ifort -O3 -qopt-report=3 -qopt-report-phase=par -parallel prog.f90
$ icc -O3 -qopt-report=3 prog.c
$ icc -O3 -qopt-report-file=my_report_file prog.c
$ icc -O3 -qopt-report=3 -qopt-report-phase=par -parallel prog.c

Options de débogage des compilateurs Fortran et C/C++

Dans une phase de débogage, les options suivantes peuvent être utilisées avec le compilateur Fortran comme avec le compilateur C/C++. Nous vous invitons à consulter l'aide des compilateurs sur Jean Zay (commandes man ifort et man icc) pour obtenir de plus amples informations.

Options de débogage Commentaires
-g Génère la table des symboles (numéros de ligne, variables, …) qui pourra ensuite être exploitée par un débogueur. Cette option conserve le niveau d'optimisation explicitement demandé (-O1, -O2 ou -O3). Sans niveau d'optimisation spécifié explicitement, cette option désactive toute optimisation (-g est équivalent à -g -O0).
-debug ou -debug full ou -debug all Génèrent les informations complètes de débogage. Recommandées lorsque l'on combine -g avec un niveau d'optimisation spécifique (-O1, -O2 ou -O3) : par exemple -g -O2 -debug.
-traceback Permet d'obtenir plus d'information lorsqu'une erreur se produit à l'exécution. Cette option est aussi positionnée avec -g.
-ftrapuv Initialise les variables locales dans la stack à des valeurs aberrantes (entier très grand, adresse invalide). Ceci permet de détecter les variables non initialisées en provoquant une erreur à l'exécution. Notez qu'elle positionne aussi l'option -g.
-check uninit (Fortran) -check=uninit (C) Détecte à l'exécution si les variables scalaires de type intrinsèque (integer, real, complex ou logical) et sans attribut SAVE ne sont pas initialisées.
-fp-stack-check Permet de générer une exception dès qu'un appel de fonction retourne une valeur incorrecte.
-no-ftz L'option -ftz est positionnée par défaut avec les optimisations -O1, -O2 et -O3; elle met à zéro les nombres dé-normalisés très petits durant l'exécution, ce qui peut produire des résultats erronés. Il est possible de désactiver cette fonctionnalité en ajoutant l'option -no-ftz afin de détecter ces underflows.

Options de débogage du compilateur Fortran

Avec le compilateur Fortran, vous pouvez aussi utiliser les options suivantes :

Options de débogage Commentaires
-debug-parameters all Génère des informations de debug pour les variables de type PARAMETER. Ceci est nécessaire pour voir les valeurs des PARAMETER avec un debugueur.
-heap-arrays Place tous les tableaux temporaires ou automatiques dans le heap au lieu de la stack si cette dernière se révèle trop petite.
-init=arrays,snan Force à NaN toutes les variables de type intrinsèque ainsi que les tableaux non initialisés. Cette option implique -fpe0. Pour éviter de récupérer des exceptions, qui ne soient pas relatives à des variables non-initialisées, nous recommandons de réduire le niveau d'optimisation à -O1 ou -O0 ou alors d'utiliser -fp-speculation=safe pour faire la détection de variables non-initialisés.
-fpe-all=0 -no-ftz -traceback Cette combinaison d'options stoppe l'exécution dès qu'une exception (overflow, underflow, division par zéro, opération invalide,…) se produit; elle indique à quel niveau du code elle s'est produite. Le contrôle s'opère dans chaque subroutine, contrairement à l'option -fpe0 qui agit uniquement sur le programme principal.
-check bounds Détecte à la compilation et à l'exécution si un tableau est adressé en dehors de ses bornes (bound checking).
-check pointers Détecte à l'exécution si un pointeur est initialisé ou non, si un tableau allocatable est alloué ou non lors de l'utilisation des pointeurs.
-check all Active les deux options listées ci-dessus simultanément.
-warn declarations Génère les messages signalant toutes les variables non déclarées (comme si le code source comportait un IMPLICIT NONE).
-warn interfaces Génère les messages signalant les incohérences entre les appels et les définitions de chaque sous-routine et chaque fonction du code. Notez que le compilateur génère un bloc d'interface pour chacune d'entre elles (option -gen-interfaces implicite).
-warn truncated_source Pour les fichiers au format fixe, le compilateur émettra un message si une ligne du source dépasse la longueur maximale autorisée (défaut : 72 caractères). Notez que cette longueur peut être portée à 132 caractères maximum avec l'option -extend_source.
-warn all ou -warn Génèrent les divers messages d'avertissement simultanément (notamment ceux cités ci-dessus).
-stand f08 Des avertissements sont générés si la norme Fortran 2008 n'est pas respectée.

Options de débogage du compilateur C/C++

Avec le compilateur C/C++, vous pouvez aussi utiliser l'option suivante :

Options de débogage Commentaires
-check-pointers=rw Permet de détecter à l'​exécution les accès mémoire invalides lors de l'utilisation de pointeurs (cela inclut l'utilisation des tableaux, qu'ils aient été alloués dynamiquement ou non).

Exemples :

$ ifort -g -debug -fpe-all=0 -no-ftz -traceback -fp-stack-check -check all -warn all -stand f08 my_prog.f90
$ icc -g -debug -no-ftz -traceback -fp-stack-check -check=uninit -check-pointers=rw my_prog.c

Liste des options activées pour le compilateur Fortran

La liste des options activées par défaut par Intel peut évoluer dans le temps, mais aussi en fonction du contexte d'appel du compilateur. Ainsi, il est possible qu'avec des versions différentes une compilation que vous lanciez sur un même code avec les mêmes options génère un exécutable qui ne donne pas exactement les mêmes resultats. Il est donc utile de générer un listing de la compilation d'un fichier source en utilisant l'option -list :

$ ifort -list prog.f90

Cette commande crée le fichier prog.lst dans le même répertoire que le fichier source
Par défaut, il contient :

  • le contenu des fichiers inclus via l'instruction INCLUDE,
  • la liste des symboles pour chaque sous-routine,
  • la liste des options de compilation.

L'option -show mot-clef permet restreindre l'action de l'option -list :

  • -show noinclude supprime le contenu des fichiers inclus via l'instruction INCLUDE,
  • -show nomap supprime la liste des symboles pour chaque sous-routine,
  • -show nooptions supprime la liste des options de compilation.

Taille des différents types de base Fortran

Les variables déclarées à l'aide des types par défaut INTEGER, REAL ou COMPLEX font l'objet d'une réservation en mémoire basée sur des mots de 4 octets. Le paramètre optionnel KIND=n indiqué à la suite du type dans le code source permet d'influer sur cette taille ; c'est la façon la plus explicite et la plus sûre de le faire.

Il existe par ailleurs des options de compilation permettant de modifier de façon globale la longueur des variables, mais nous déconseillons formellement leur utilisation pour des raisons de portabilité :

  • les options équivalentes ne fonctionnent pas de la même façon sur des plateformes différentes,
  • il est très facile d'oublier ces options lorsqu'on compile son code ou qu'on le partage avec quelqu'un d'autre; dans ce cas les résultats de l'exécution sont faux !

Afin de permettre quelques tests ponctuels, ces options sont les suivantes :

  • -integer-size 16/32/64 force la réservation en mémoire des entiers et logiques déclarés avec le type INTEGER ou LOGICAL (sans spécification du paramètre KIND=n) sur des mots de 2/4/8 octets (4 par défaut);
  • -real-size 32/64/128 : les entités déclarées avec le type REAL ou COMPLEX (sans spécification du paramètre KIND=n) sont promues respectivement sur 4, 8 et 16 octets.

Lire ou écrire un fichier binaire IEEE big-endian en Fortran

Jean Zay est une machine Linux : par défaut, elle génère donc des fichiers binaires Fortran au format little-endian. Pour écrire ou lire un fichier binaire IEEE big-endian en Fortran, il faut utiliser la variable d'environnement F_UFMTENDIAN.
Pour lire un fichier binaire écrit en big-endian (provenant par exemple de notre ancienne IBM Power6 Vargas) sur l'unité 12 :

$ ifort -o prog_big_endian prog_big_endian.f90
$ export F_UFMTENDIAN=big:12
$ ./prog_big_endian

Remarque : Si vous ne spécifiez pas de numéro d'unité logique, alors la variable opère sur toutes les unités. Par conséquent tous les fichiers sont considérés comme ayant le même format (big-endian dans cet exemple) :

$ ifort -o prog_big_endian prog_big_endian.f90
$ export F_UFMTENDIAN=big
$ ./prog_big_endian

Il est possible de spécifier plusieurs unités logiques; ici, les unités 12, 15 et toutes celles de 20 à 30 :

$ export F_UFMTENDIAN="big:12,15,20-30"
$ ./prog_big_endian

Attention : dans le cas d'un fichier à accès direct, la taille de l'enregistrement, indiqué lors de l'OPEN du fichier dans le code source au moyen du mot-clef RECL, est interprété en mots de 4 octets. Pour spécifier cette taille d'enregistrement directement en octets lors de l'OPEN, il faut compiler avec l'option -assume byterecl :

$ ifort -assume byterecl -o prog_big_endian prog_big_endian.f90
$ export F_UFMTENDIAN=big:12
$ ./prog_big_endian