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 vit toujours
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), et un vrai plat de
spaghetti historique (spaghetti.f) avec sa version dénoué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 — et c'est voulu :
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 »
C'est le premier acte de « l'histoire de la racine cubique » — dont le dernier mot sera dit en
clôture du Jour 9. 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. Testé, sinon rien
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 — le cabinet de curiosités
La signature pédagogique de 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.
En vidéo — les replays officiels
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
- 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.