Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Écrire un noyau de calcul GPU

Après cette leçon: Je peux écrire un noyau pour un calcul simple et le lancer.

Leçon de 60 min1 commandeLab de calcul parallèle : comment pense un GPU, sans GPU, dans JupyterLab

Un noyau décrit le travail d’un seul fil

Un noyau est la petite fonction que chaque fil d’un GPU exécute sur son propre élément. Écrire un noyau, c’est dire ce que fait un seul fil : le lancement le répète ensuite des milliers de fois.

Un magasin additionne les stocks de deux entrepôts, case par case. Le labo n’a pas de GPU : une boucle simule le lancement, et le noyau est une vraie fonction Python.

À la fin de cette leçon

Remarque

Je peux écrire un noyau pour un calcul simple et le lancer.

Mots clés

MotCe que ça veut dire
Noyaula fonction que chaque fil exécute
Lancementle départ de tous les fils d’une grille
Gardele test qui empêche un fil sans élément d’écrire
Taille de blocle nombre de fils dans chaque bloc
Sortiele tableau où chaque fil écrit son résultat
Conflit d’écrituredeux fils qui écrivent la même case

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Un noyau calcule son indice puis son résultat

Un noyau fait trois choses. Un : il calcule son indice global avec son bloc et son fil. Deux : il vérifie que l’indice existe. Trois : il lit ses données et écrit son résultat dans la case de même indice.

Le noyau ne connaît pas les autres fils. Il ne voit que son élément.

Lire le noyau du labo

Commande
docker exec jupyter cat steps/kernel.py

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Un noyau qui double des nombres

Code: python
# Un noyau qui double chaque nombre, lancé par blocs de 2 fils.
entree = [3, 1, 4, 1, 5]
taille_bloc = 2
n = len(entree)
sortie = [0] * n

def noyau_doubler(bloc, fil):
    i = bloc * taille_bloc + fil
    if i < n:
        sortie[i] = entree[i] * 2

nombre_blocs = (n + taille_bloc - 1) // taille_bloc
for bloc in range(nombre_blocs):
    for fil in range(taille_bloc):
        noyau_doubler(bloc, fil)
print(nombre_blocs, "blocs")
print(sortie)
# Remplacez i < n par i < n + 1 : le dernier fil plante. Pourquoi ?

La garde protège la fin des données

On lance toujours des blocs entiers. Pour 5 éléments et des blocs de 2 fils, on lance 6 fils : le dernier tombe à l’indice 5, qui n’existe pas.

La garde if i < n fait que ce fil ne fait rien. Sans elle, il écrit hors du tableau.

Exemple : cinq éléments, blocs de deux fils

BlocFilIndiceCe qui se passe
00 et 10 et 1Il écrit les cases 0 et 1
10 et 12 et 3Il écrit les cases 2 et 3
204Il écrit la case 4
215La garde l’arrête : rien n’est écrit

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Chaque fil écrit sa propre case

Ce qui rend un noyau sûr, c’est que chaque fil écrit une case que personne d’autre n’écrit : celle de son indice. Les fils peuvent alors partir dans n’importe quel ordre.

Si tous les fils additionnent dans une même case, ils se gênent : c’est un conflit d’écriture, et le résultat devient imprévisible.

Une erreur fréquente

Attention

On croit souvent que le numéro de fil suffit pour choisir l’élément. Le numéro de fil recommence à 0 dans chaque bloc : tous les blocs écriraient les mêmes cases. Il faut l’indice global, bloc fois taille de bloc plus fil.

À propos de ce labo et de sa source: Lab de calcul parallèle : comment pense un GPU, sans GPU, dans JupyterLab

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.