Lab de calcul parallèle : comment pense un GPU, sans GPU, dans JupyterLab

Ce lab donne à chaque élève un JupyterLab à lui pour les idées sur lesquelles repose un GPU : une opération sur une multitude de nombres, un travail partagé entre ouvriers, la limite de ce que cela peut accélérer, un lancement de blocs de fils d’exécution qui trouvent chacun leur élément, et le coût du déplacement des données. Il n’y a pas de GPU dans le lab. Il enseigne le modèle avec NumPy, le multiprocessing de Python et six petits scripts.

Ce n’est pas un lab d’attaque. Chaque copie n’a aucun accès à internet ni à aucun autre élève : rien ne peut y être téléchargé et rien n’y peut atteindre quelqu’un d’autre.

Ce que les élèves apprennent

Qu’une seule opération NumPy fait le travail d’une boucle Python sur tout un tableau : la somme des carrés de 1 à 1000 vaut 333833500 des deux façons, avec 2000 opérations au niveau de Python pour la boucle et 1 pour NumPy. Qu’un travail peut être coupé en morceaux et partagé entre deux ouvriers, et que les sommes partielles donnent le même total. Qu’une partie de tout travail ne peut pas être découpée : avec 10 pour cent de séquentiel, 8 ouvriers donnent 4,71 fois et aucun nombre d’ouvriers ne donne plus de 10,0. Comment un noyau de GPU est lancé en blocs de fils, chacun calculant son élément avec bloc fois taille du bloc plus fil, ce qu’ils voient simulé en Python simple. Si un travail est limité par le déplacement des octets ou par les calculs, d’après un débit et une cadence donnés. Et pourquoi des fils qui lisent des nombres voisins vont chercher 1 ligne de mémoire là où des fils qui sautent en cherchent 8. Il convient aux introductions à l’architecture des ordinateurs, au calcul parallèle et haute performance et aux graphismes ; vérifiez la formulation exacte dans l’unité de votre propre organisme certificateur, aucune n’est citée ici.

Le lancer dans votre navigateur

Le lab démarre un seul service, jupyter, qui écrit le notebook et les six scripts dans son dossier de travail et il est prêt en quelques secondes, sur les 512 Mo qu’un service peut avoir. JupyterLab ne demande aucun jeton, car la porte de la plateforme sait déjà qui l’ouvre. Le terminal à côté du lab n’a pas de Python à lui : il atteint celui du lab avec docker exec jupyter, suivi de la commande à lancer à l’intérieur. Rien n’est chronométré : chaque script affiche donc la même chose à chaque fois.

  1. Ouvrir la page Conteneur. Ouvrez « Créer » dans la barre et choisissez « Lancer un conteneur ». Tout le monde peut ouvrir la page, et le lab Git et le lab SQL se lancent sans compte. Tous les autres labs demandent un compte gratuit : créez-en un, connectez-vous, puis appuyez sur « Démarrer ».
  2. Trouver le lab. La carte « Laboratoires d’exemple » liste tous les exemples. Trouvez JupyterLab : calcul parallèle sans GPU.
  3. Appuyer sur Démarrer. « Démarrer » le lance tel quel, en un clic. « Modifier le fichier d’abord » ouvre le fichier compose pour que vous puissiez le changer avant de démarrer.
  4. L’ouvrir. Sur la page du lab, la barre du lab a un lien nommé JupyterLab : appuyez dessus pour ouvrir JupyterLab dans votre navigateur, puis double-cliquez sur start.ipynb. Appuyez ensuite sur « Ouvrir le terminal » et tapez docker exec jupyter python3 steps/vectors.py pour voir les deux résultats égaux à 333833500, avec 2000 opérations pour la boucle et 1 pour NumPy.

Que demander aux élèves de rendre

Une courte modification à eux d’un script, téléchargée depuis JupyterLab avec File, Download, par exemple un autre nombre de morceaux dans chunks.py, une autre part qui ne peut pas être découpée dans amdahl.py, ou une autre taille de lancement dans kernel.py. Puis une ou deux phrases, de leurs propres mots, sur ce qui a bougé et pourquoi. Rien n’est noté automatiquement : la phrase montre si c’était compris. Pour un travail plus poussé, demandez de prévoir les nouveaux nombres avant de lancer le script, et de dire quelle limite, la partie séquentielle ou la mémoire, ils rencontreraient d’abord sur un vrai GPU.

Une leçon de base sur ce lab

Parallel Computing Basics est une petite leçon qui se fait dans ce lab. L’élève y liste les scripts, additionne des carrés avec une boucle puis avec une seule opération NumPy, partage une somme entre deux ouvriers, lit un tableau d’accélérations, lance une simulation de blocs de fils, voit lequel de deux travaux est limité par la mémoire, puis retrouve le même travail dans le notebook de départ.

Elle est volontairement petite : elle montre à un enseignant ce qu’est une leçon qui se fait dans un lab, et le lab fait le reste. Copiez-la dans un module à vous pour la modifier.

Le code sur GitHub

Le fichier compose n’a pas de Dockerfile : il lance une seule image publique, scipy-notebook des Jupyter Docker Stacks, figée sur une étiquette datée, avec son propre compte sans privilèges et 512 Mo de mémoire. L’image est sous licence BSD-3-Clause et n’est pas distribuée par nous. Le fichier écrit les scripts à partir de nombres fixes au démarrage : chaque copie affiche la même chose et rien n’est téléchargé. Les limites sont honnêtes : il n’y a pas de GPU, le lancement du noyau est donc simulé en Python et les chiffres sur le déplacement des données sont de l’arithmétique sur un appareil inventé, jamais une mesure. Rien ne peut être installé depuis internet. Rien n’est conservé quand le lab s’arrête : l’élève télécharge son travail avant.

En faire un travail

Indiquez dans la tâche ce qu’il faut rendre.

  1. Créer le lab. Dans votre module, ajoutez une tâche et choisissez la carte « Lab de conteneurs », puis « Dans un dépôt GitHub ». Indiquez https://github.com/mitsurutech/lab-parallel-lab avec la branche main. Le fichier compose par défaut est compose.yaml. Faites d’abord un fork du dépôt si vous voulez le modifier, par exemple pour changer les nombres qu’utilise un script.
  2. Publier et l’essayer. « Publier » fige le commit qui vous a été montré : un changement ultérieur dans le dépôt ne modifie donc pas un lab que vous avez déjà proposé. Démarrez d’abord votre propre copie.
  3. Le distribuer. Attribuez-le comme n’importe quelle tâche, avec une échéance si vous le souhaitez, et indiquez dans la tâche ce qu’il faut faire et ce qu’il faut rendre.
  4. Noter ce qui est rendu. Ouvrez la copie d’un élève et le travail rendu, notez-le et renvoyez-le avec un motif s’il demande un complément.

Essayer ce lab, et ce qu’il coûte

Un compte personnel gratuit permet de suivre les leçons de base de ce lab, avec chaque mois assez de crédit gratuit pour suivre la plupart des leçons, sans carte. Pour une classe, un établissement a ses 365 premiers jours gratuits pour 50 élèves au plus, puis paie par élève et par an, tous les labs compris et les enseignants gratuits.

Questions fréquentes

Y a-t-il un GPU dans le lab ?
Non. Le lab enseigne le modèle sur lequel un GPU est construit, avec NumPy, le multiprocessing de Python et de courts scripts. Le lancement du noyau est simulé en Python simple, et les chiffres sur le déplacement des données sont de l’arithmétique sur un appareil inventé : l’élève apprend à penser un GPU sans en avoir un.
Pourquoi le terminal utilise-t-il docker exec jupyter ?
Le terminal du lab contient curl, psql et quelques autres clients, mais pas Python. docker exec jupyter lance une commande dans le conteneur du lab, qui a Python et NumPy. JupyterLab a aussi son propre terminal, sous File, New, Terminal.
Pourquoi rien n’affiche-t-il de durée ?
Une durée change d’une exécution à l’autre et d’une machine à l’autre : la leçon ne pourrait pas dire ce que l’élève doit voir. Les scripts comptent donc des opérations et calculent des chiffres à partir d’un débit et d’une cadence donnés : chaque exécution affiche la même chose et chaque réponse se vérifie à la main.