Jour 3 — Fortran sur CPU
24 juin 2026 · Intervenant : Vincent Lafage (IJCLab) · Auditorium Marcel Vivargent + sites satellites (dont la CINERI) · au déjeuner, visite du Musée du LAPP. Le TP du jour vit dans
GrayScott2026/day-3-a/— CPU uniquement : les dossiersGPU/etCUDA/du même dépôt serviront au Jour 8.
Session du matin — Fortran moderne, le langage des tableaux
1. Fortran moderne
Le cours s'ouvre sur une démonstration par l'exemple : le dossier Annexe/ contient le même
programme en FORTRAN 66 (obact66.f) et en Fortran 95 (obact95.f90), ainsi qu'un exemple
historique de code non structuré (spaghetti.f) et sa version restructurée (unspaghetti.f). Le langage de
1957 est devenu un langage moderne — modules, interfaces génériques, coarrays — sans
perdre sa spécialité : les tableaux numériques.
2. Column-major — le piège venu du C
Première différence structurante avec le C/C++ : l'ordre mémoire.
Tout ce qu'on a appris au Jour 2 sur le parcours mémoire reste vrai — mais inversé : en Fortran, la boucle interne doit parcourir la première dimension. Un réflexe C recopié tel quel divise le débit.
3. Le solveur en quatre modules
Le Gray-Scott du TP est découpé proprement (src/) :
| Module | Rôle |
|---|---|
floating_point_precision.f90 | le kind pr — toute la précision du solveur en une ligne |
gray_scott_settings.f90 | paramètres physiques + namelist (config sans recompiler) |
hdf5_utils.f90 | écriture HDF5 des images |
gray_scott.f90 | le programme : init → evolve → sortie |
Le stencil du Laplacien est choisi parmi quatre variantes (isotropie vs précision) :
| Stencil | Centre | Note |
|---|---|---|
| Différences centrées | −4 | le 5-points classique |
| Weights-pretty (défaut) | −8 | isotrope, utilisé ici |
| Oono-Puri (1988) | −12/4 | meilleure isotropie |
| Patra-Karttunen | −20/6 | précis à l'ordre 4 |
Le centre pèse −8, ses huit voisins +1.
4. Dire son intention au compilateur
Les mots-clés modernes sont des promesses que le compilateur sait exploiter :
pure / elemental (pas d'effet de bord), contiguous (mémoire dense), do concurrent
(itérations indépendantes — la clé des Jours 8-9), et les opérations tableau
(sum(stencil * U(i-1:i+1, j-1:j+1))) qui disent quoi calculer, pas comment.
Session de l'après-midi — Précision, flags, variantes
5. La précision en une ligne
Le module de précision du TP tient en trois lignes :
module floating_point_precision
use, intrinsic :: iso_fortran_env, only: pr => REAL32
end module
Changer REAL32 en REAL64 bascule tout le solveur. Ce qu'on échange :
6. La sommation compensée
L'ordre de sommation change le résultat flottant. Le TP implémente les quatre remèdes
classiques (Solutions/compensated_summation.f90 — interfaces génériques 1D/2D) :
| Méthode | Idée |
|---|---|
sum_pairwise | sommation récursive diviser-pour-régner |
sum_Kahan | on traîne un terme de compensation |
sum_Neumaier | robuste quand le terme suivant est plus grand |
sum_KBN | Kahan-Babuška-Neumaier, le défaut pratique |
7. L'exercice des flags — mêmes sources, ×6 à ×8
Le script run_flags_exo.sh du TP fait la démonstration de bout en bout, mesures à l'appui :
- Détecter le SIMD du CPU (
/proc/cpuinfo: AVX2 ? AVX-512 ?) ; - C :
speedcbrtf.ccompilé scalaire (-O2 -fno-tree-vectorize) puis natif (-Ofast -march=native -ftree-vectorize -mrecip …) — on compte les registresymmdans le binaire (objdump | grep -c ymm) pour prouver la vectorisation ; - Fortran :
gfortran -fopt-info-vecaffiche les boucles vectorisées, et-fopt-info-vec-missedexplique pourquoi une boucle est refusée.
cd GrayScott2026/day-3-a
pixi run bash run_flags_exo.sh # « les mêmes sources, ×6-8 selon les flags »
Ce sujet est repris en clôture du Jour 9 (A story about cubic root optimisation). Pour aller plus loin : maqao cqa --fct-loops=loop_cbrt analyse la boucle
au niveau assembleur (dossiers OptimisationCbrtC/ et OptimisationCbrtFortran/).
8. Les variantes du dépôt — un solveur, dix expériences
Solutions/ décline le même solveur pour isoler chaque idée :
| Variante | Ce qu'elle isole |
|---|---|
preopenmp → openmp → openmp_bis (+ _ptr) | la parallélisation !$omp pas à pas |
blocking_ptr | le blocking du Jour 2, en Fortran |
RK / CK | intégrateurs Runge-Kutta / Cash-Karp — la précision temporelle |
stdpar / openacc / openmp_offload | les back-ends GPU — rendez-vous au Jour 8 |
| Variante | Mécanisme | Cible |
|---|---|---|
openmp | directives !$omp | cœurs CPU |
stdpar | do concurrent | CPU multicœur ou GPU |
openacc / openmp_offload | directives | GPU (Jour 8) |
9. Tests
Solutions/test_stencil.f90 vérifie les invariants du stencil (multiple du Laplacien,
normalisation) avec tolérance — l'application directe des règles du Jour 1. Et l'Annexe/
montre les tests pFUnit (test_roman_numeral.pf, test_divisor.pf) : le framework de
tests unitaires du monde Fortran.
L'Annexe
Exemples pédagogiques fournis par Vincent Lafage : santa_claus_problem_caf.f90 (le problème du
Père Noël… en coarrays, le parallélisme natif de Fortran 2008), roman_numeral.F90 (+ ses
tests), physconst.f90, decimal_interface.f90, et le duo spaghetti.f / unspaghetti.f
qui résume 60 ans d'évolution du langage.
Le live du jour
Sources & matériel officiel
- Le dépôt du cours : gitlab.in2p3.fr/lafage/GrayScottFortranTuto
- Les slides du jour (PDF, wiki GitLab de l'école) : FortranFurious — IJC dual GS 2026
- pFUnit (tests unitaires Fortran) : github.com/Goddard-Fortran-Ecosystem/pFUnit_demos
- Replays vidéo (YouTube) : Gray Scott Thursdays — épisodes liés : Fortran On CPU · Computing Precision
- Conteneurs du cours (podman/apptainer, images
grayscott_fortran_*) : liste des conteneurs · site de l'école
Jour 2 — C++ sur CPU
Deux sessions le 23 juin : C++ 17/20/23 sur CPU le matin, optimisation avancée (blocking & Pyramide) l'après-midi. Mesurer, comprendre le stencil, exploiter le cache.
Jour 4 — Kokkos sur CPU
25 juin, avec Paul Zehner, Juan-José Silva Cuevas et Thomas Padioleau : Kokkos sur CPU — une seule source C++, des backends choisis à la compilation, Views, parallel_for et SIMD.