Ceci est une ancienne révision du document !
Nous avons vu dans l'introduction à la MKL que cette librairie est par défaut en mode multi-threadé.
L'objet de cet article est d'exposer dans les grandes lignes :
Nous rappelons que la MKL est thread-safe.
Autrement dit, si votre programme est déjà multi-threadé (quel que soit le moyen utilisé) et que vous faites appel à la MKL dans des threads, l'exécution du programme ne risque pas de “planter” ou de générer des résultats aléatoires.
Si votre programme utilise les compilateurs Intel et OpenMP, la MKL gérera parfaitement les inter-actions, car elle utilise la même librairie de parallélisation. C'est le cas général.
Par contre, si votre code utilise un autre mécanisme de multi-threading, ou un autre compilateur, des inter-actions malvenues surviendront. Le code fonctionnera, mais l'utilisation des ressources sera sous-optimisé, en générant plus de threads que le système n'a de ressources. Vous devez absolument consulter la documentation (section Avoiding Conflicts in the Execution Environment) pour gérer ce cas.
Nous arrivons maintenant à la partie critique. Si vous compilez votre programme avec la MKL en mode threadé (mode par défaut pour rappel), vous devez absolument comprendre comment votre code, à travers les appels à la MKL, consommera des cœurs sur les nœuds calcul.
Dans un cas “standard”, plus précisément :
alors la couche de threading utilisera tous les cœurs disponibles sur la machine.
Il est donc très important de prendre cela en compte quand vous lancerez un job sous slurm : il faudra dans ce cas réserver un nœud complet pour votre job, sinon le nœud sera en sur-allocation.
Si l'appel à une méthode threadée de la MKL survient à l'intérieur d'un thread de votre programme, et que vous utilisez OpenMP plus les compilateurs Intel, alors la MKL détectera qu'elle est déjà dans une zone threadée, et par défaut ne lancera pas de thread (fonctionnement par défaut modifiable).
Autrement dit, elle se comportera en mode séquentiel.
Plusieurs techniques sont possibles pour fixer explicitement le nombre de threads :
Le plus simple consiste à utiliser une des deux variables suivantes :
OMP_NUM_THREADS
, la variable générale d'OpenMP spécifiant le nombre de threads possiblesMKL_NUM_THREADS
, variable spécifique à la MKL. Elle permet alors d'avoir un comportement différent entre la MKL et le reste de votre programme si vous utilisez aussi OpenMP dans votre code.