Ressources de calcul et gestion des ressources
Modèle de ressources et ressources classiques
Dans cette section, nous te proposons un cadre pour réfléchir aux environnements de calcul, applicable aussi bien à un ordinateur portable qu'à des supercalculateurs. À la fin de cette section, tu comprendras les composants fondamentaux d'un environnement de calcul et la façon dont ils s'articulent entre eux. Tout cela est présenté par Iskandar Sitdikov dans la vidéo suivante.
Modèle de ressources
Tout environnement de calcul classique repose sur plusieurs ressources interdépendantes qui coopèrent pour exécuter des applications de manière efficace. Les ressources clés comprennent généralement :
-
CPU (Central Processing Unit) : Le CPU est l'unité de traitement centrale qui interprète et exécute les instructions d'un programme. Il gère les opérations logiques, arithmétiques et de contrôle, et agit essentiellement comme le « cerveau » du système.
-
Cache CPU (L1, L2, L3) : Il s'agit de la mémoire la plus rapide du système, intégrée directement dans le cœur du CPU ou très proche de lui. Elle stocke de petites portions de données et d'instructions dont le CPU a besoin immédiatement. Les différents niveaux (L1, L2, L3) représentent un compromis : L1 est le plus petit et le plus rapide, tandis que L3 est le plus grand et le plus lent, mais reste de plusieurs ordres de grandeur plus rapide que la RAM.
-
RAM (Random Access Memory) : Mémoire volatile offrant un stockage temporaire et volumineux pour les instructions des programmes et les données en cours d'utilisation. Elle permet au CPU d'accéder rapidement aux informations nécessaires pendant l'exécution, sans dépendre constamment de dispositifs de stockage plus lents.
-
Stockage (local et réseau) : Le stockage conserve les données et les logiciels même lorsque le système est éteint, assurant une persistance à long terme pour les grands ensembles de données et les applications. Dans le calcul haute performance, les solutions de stockage doivent gérer des volumes considérables de données scientifiques ou analytiques avec à la fois rapidité et fiabilité. Le stockage local inclut les disques SSD et les disques durs HDD, les SSD étant préférés pour leur faible latence et leur débit élevé. Pour la gestion de données à grande échelle, les systèmes de fichiers parallèles, le stockage réseau partagé et les systèmes à objets permettent un accès rapide à de nombreux nœuds de calcul, tandis que le stockage en nuage et les niveaux d'archivage assurent la conservation à long terme et la scalabilité.
-
GPU (Graphics Processing Unit) : Initialement conçu pour le rendu graphique, le GPU moderne est un puissant processeur parallèle. Il est largement utilisé pour des tâches nécessitant de nombreux calculs simultanés, comme l'apprentissage profond, les simulations physiques et l'analyse de grandes masses de données. Il est important de noter que les GPUs ne remplacent pas les CPUs : les CPUs gèrent la logique de haut niveau du programme, tandis que les GPUs accélèrent les étapes hautement parallèles.
-
Connexions/Bus : Ce sont les voies de communication reliant le CPU, la mémoire, le stockage et les périphériques. Les bus permettent le transfert de données et la coordination entre les parties du système, assurant une communication fluide dans l'environnement de calcul. Dans les systèmes HPC, les composants tels que les CPUs, GPUs et dispositifs de stockage sont reliés par des interconnexions à haute vitesse permettant un échange rapide de données. Les GPUs se connectent généralement au système via PCIe, une interface standard à plusieurs voies de données pour une communication efficace. Pour de meilleures performances, NVLink fournit un lien direct à haute bande passante entre les GPUs, ou entre les GPUs et les CPUs, réduisant la latence et accélérant les charges de travail parallèles.
-
Système de fichiers : Le système de fichiers organise les données sur les dispositifs de stockage. Il fournit une structure pour stocker, récupérer et gérer les fichiers, permettant aux programmes et aux utilisateurs d'accéder aux informations de manière cohérente et logique.
Chaque type de ressource possède ses propres unités de mesure liées aux performances. Par exemple, les CPUs sont généralement mesurés en « cœurs » et en « vitesse d'horloge ». Lors de l'achat d'un ordinateur portable, ses caractéristiques incluent habituellement le nombre de cœurs. Un concept similaire s'applique aux nœuds de calcul d'un centre de données, où chaque nœud est associé à un nombre précis de cœurs. Les environnements de calcul qui incluent plusieurs types de ressources (CPUs, GPUs, voire des QPUs) sont appelés environnements de calcul hétérogènes. Ces configurations gèrent les charges de travail diversifiées plus efficacement en exploitant les atouts de chaque type de processeur. Par exemple, les CPUs seraient utilisés pour les tâches générales et les GPUs pour le traitement parallèle. Dans le contexte de la gestion et de l'ordonnancement des ressources — notamment dans les environnements de calcul hétérogènes — des unités de mesure supplémentaires peuvent être nécessaires en plus de celles décrites ici.
Pour la mémoire, l'unité de mesure est le Méga/Giga/Téraoctet.
Pour les cartes graphiques et autres accélérateurs, l'unité de mesure dépend du contexte. Si leur capacité de calcul réelle est mesurée par des métriques fines — nombre de cœurs de traitement, taille de la mémoire et bande passante mémoire —, dans les discussions de haut niveau sur les ressources de cluster ou l'ordonnancement des tâches, les GPUs et accélérateurs similaires peuvent être quantifiés au niveau des dispositifs, par le nombre d'unités complètes attribuées (par exemple, trois GPUs).
Le réseau/connectivité/bus est un aspect crucial de toute infrastructure de calcul, car il détermine la vitesse de transfert des données entre les composants. Du CPU au cache du CPU, à la RAM, aux cartes PCI, aux appareils connectés au réseau : tout cela relève de la communication, et il est essentiel d'en avoir une représentation mentale précise pour concevoir des algorithmes hautement optimisés pour le HPC.
Mise à l'échelle des ressources classiques
Le calcul haute performance (HPC) consiste à faire évoluer ces ressources classiques pour obtenir des temps de traitement plus rapides ou augmenter le volume de données pouvant être traité simultanément (par exemple, pour agrandir l'espace de solutions consultables). Cela peut être réalisé par :
-
Mise à l'échelle verticale : Augmenter la puissance des ressources individuelles, par exemple en utilisant un CPU plus puissant ou en ajoutant de la mémoire au sein d'un seul nœud physique, un nœud étant une unité d'un cluster de calcul regroupant plusieurs ressources de calcul en son sein.
-
Mise à l'échelle horizontale : Ajouter davantage de ressources, telles que plusieurs CPUs ou GPUs, pour travailler ensemble sur un même nœud ou, plus couramment, sur plusieurs nœuds, permettant ainsi le calcul distribué.
Certains concepts de mise à l'échelle de cette section s'appliqueront à la prochaine section sur les ressources de calcul quantique. D'autres aspects des ressources quantiques seront quantifiés de manière nouvelle.
Vérifie ta compréhension
À partir des descriptions ci-dessus, déduire quelques avantages et inconvénients des deux approches de mise à l'échelle : verticale et horizontale.
Réponse :
Il peut y avoir de nombreuses bonnes réponses. La mise à l'échelle verticale est souvent plus simple, surtout si tu as des charges de travail prévisibles nécessitant un volume fixe de ressources. Mais elle peut être plus coûteuse à mettre à niveau, car l'unité fondamentale de calcul ne peut pas être décomposée aussi facilement que dans la mise à l'échelle horizontale. La mise à l'échelle horizontale est plus complexe à gérer et on rencontre parfois des difficultés ou des latences liées aux connexions entre les nœuds. Mais elle s'adapte bien mieux aux besoins variables en ressources et elle est modulaire lors des mises à niveau.
Nouveau type de ressource : QPU (Quantum Processing Unit)
Dans cette section, nous allons introduire un nouveau type de ressource — une ressource quantique — et explorer sa définition, ses unités de mesure et sa connectivité avec l'infrastructure classique.
Définition du QPU
- Unité de traitement quantique (QPU) : Un QPU comprend tout le matériel responsable de l'acceptation d'un jeu d'instructions quantiques exécutable, ou d'un circuit quantique, et du renvoi d'une réponse précise.
Cela signifie que le QPU comprend une ou plusieurs puces quantiques (par exemple Heron), les nombreux composants supplémentaires dans le réfrigérateur à dilution tels que les amplificateurs quantiques, l'électronique de contrôle, et le calcul classique nécessaire à des tâches comme la conservation en mémoire des instructions et des formes d'ondes, l'accumulation des résultats, et le futur décodage de la correction d'erreurs. Bien qu'un réfrigérateur à dilution soit nécessaire pour effectuer ces tâches, nous l'excluons de cette définition afin de laisser la possibilité d'avoir plusieurs QPUs dans le même réfrigérateur.
-
Ordinateur quantique : Un ordinateur quantique est constitué du QPU ainsi que du calcul classique qui héberge l'environnement d'exécution.
-
Environnement d'exécution : La combinaison de matériel et de logiciel qui rend possible l'exécution d'un programme.
Couches dans les circuits quantiques
Aussi bien en informatique classique que quantique, les processus peuvent être exécutés séquentiellement ou en parallèle. Comme les qubits ont un espace d'état bien plus riche que les bits classiques, il est parfois judicieux d'exécuter plusieurs portes à qubit unique en séquence sur un même qubit (par exemple une porte R_x suivie d'une porte R_z). Puisque l'intrication entre qubits est essentielle au calcul quantique, il est également courant qu'un circuit quantique comporte un ensemble de portes d'intrication agissant sur de nombreux qubits. Ces facteurs et d'autres font qu'il est fréquent d'identifier des processus pouvant être exécutés en parallèle à l'échelle des opérations de portes individuelles dans un circuit quantique. En informatique classique, le parallélisme au niveau des bits est aussi possible, mais il est moins souvent considéré au niveau des portes ; on préfère généralement parler de processus parallèles et séquentiels à une échelle plus grande.
En informatique quantique, on parle de « couche » de portes pouvant toutes être exécutées simultanément. Dans de nombreuses applications, il est utile d'effectuer un ensemble de rotations sur tous les qubits, puis des portes d'intrication entre paires de qubits. Dans ces contextes, on parle de « couche de rotation » (une couche de portes comme R_x, R_y, et/ou R_z) et de « couche d'intrication » (comme celle comportant des portes CNOT). Le nombre de couches dans un circuit est la « profondeur du circuit », une mesure importante car une profondeur plus grande implique davantage de couches de bruit et d'erreurs qui s'accumulent.
Il peut être difficile d'identifier visuellement les couches de portes lorsqu'elles ne sont pas alignées à l'aide de barrières. Dans Qiskit, une barrière est une instruction dans les circuits quantiques qui agit comme un séparateur visuel et une contrainte lors de la compilation. Aussi bien lors du tracé du circuit que de son exécution, aucune porte ne sera déplacée au-delà de la barrière. Cela peut être important dans des contextes comme le découplage dynamique, où l'on implémente intentionnellement des portes qui se simplifient en une identité pour supprimer certains types d'erreurs. Pour en savoir plus sur le découplage dynamique, consulte ce guide. Pour voir l'effet visuel des barrières, compare ces deux images du même circuit : la première sans barrières et la seconde avec des barrières pour forcer l'alignement des couches.
Il s'agit du même circuit et il a le même nombre de couches. Mais dans le second, l'alignement permet de voir facilement que le circuit comporte :
- Deux couches de rotation : une autour de l'axe Y par , une autour de l'axe Z par .
- Trois couches d'intrication. À noter qu'on peut considérer chaque CNOT comme une « couche » à part entière, car les CNOTs ne peuvent pas être réordonnés pour être parallèles sans modifier l'opération logique.
- Deux autres couches de rotation : une autour de l'axe Y par , une autour de l'axe Z par .
- Deux autres couches d'intrication. À noter que cette fois, la première couche est légèrement plus parallélisée que dans le premier ensemble de couches d'intrication.
La profondeur de chaque circuit est 9.
Unités de mesure
En informatique quantique, les capacités d'un système quantique sont généralement évaluées à l'aide de trois métriques de performance clés : l'échelle, la qualité et la vitesse. Ces métriques décrivent non seulement le potentiel de calcul d'un dispositif quantique, mais aussi la façon dont les ressources sont gérées et ordonnancées dans les applications pratiques.
-
L'échelle désigne le nombre de bits quantiques (qubits) dans le système, représentant la quantité d'information quantique que le dispositif peut contenir. Dans la gestion des ressources, cela a un impact direct sur la largeur du circuit — le nombre de qubits nécessaires pour exécuter une tâche quantique donnée. Une unité quantique doit disposer de suffisamment de qubits pour prendre en charge la tâche assignée.
-
La qualité décrit la précision avec laquelle les opérations quantiques sont réalisées. Elle est souvent quantifiée par la fidélité de couche, qui mesure la précision de l'exécution d'une couche complète de portes quantiques sur tous les qubits. Du point de vue de l'ordonnancement, une fidélité plus élevée permet d'exécuter des circuits plus profonds de manière fiable, influençant le besoin de mitigation d'erreurs ou de décomposition de tâches.
-
La vitesse est mesurée par les CLOPS (Circuit Layer Operations Per Second), indiquant combien de couches d'opérations quantiques le système peut exécuter par seconde. Cela affecte le débit et la latence dans l'exécution des tâches, et aide à déterminer la rapidité à laquelle une unité quantique peut accomplir une charge de travail donnée. Cette vitesse est particulièrement importante sur un ordinateur quantique, car les qubits souffrent de bruit et d'erreurs dans une plus grande mesure que leurs homologues classiques. La durée pendant laquelle ils peuvent conserver leur information quantique de manière utile est décrite par le temps de cohérence, généralement de l'ordre de 200 à 300 pour les processeurs Heron r3.
Différences entre les métriques quantiques et classiques
On peut considérer les CLOPS comme un équivalent quantique approximatif des FLOPS, mais avec quelques différences essentielles. Les CLOPS mesurent la vitesse à laquelle un processeur quantique peut exécuter des circuits quantiques, plus précisément des couches d'opérations au sein de ces circuits, incluant à la fois les calculs quantiques et les calculs classiques nécessaires à l'exécution des circuits. Ils ont été développés par IBM Quantum comme mesure globale de la vitesse d'exécution d'un ordinateur quantique, couvrant le temps d'exécution quantique et le traitement classique en temps réel nécessaire aux mises à jour de circuits, contrairement aux FLOPS qui mesurent purement la capacité arithmétique en virgule flottante des processeurs classiques.
Les CLOPS fournissent une métrique de performance mesurable qui peut être évaluée sur le matériel existant. IBM Quantum a utilisé les CLOPS pour comparer différents processeurs quantiques, et les valeurs peuvent être consultées sur la page Ressources de calcul d'IBM Quantum Platform. Les valeurs de CLOPS dépendent des capacités matérielles, de la vitesse des portes, de la vitesse de traitement classique et de leur intégration.
Le nombre de qubits est un nombre fixe pour un QPU donné. Les CLOPS et la qualité dépendent de l'étalonnage et de la maintenance réguliers et peuvent varier légèrement au fil du temps, même pour un seul QPU.
Ensemble, ces métriques guident l'allocation et l'ordonnancement des systèmes quantiques. Dans de nombreux cas, le système quantique entier est traité comme une seule unité. Cependant, lorsqu'une tâche dépasse la capacité d'une unité — que ce soit en termes de nombre de qubits, de profondeur du circuit ou de vitesse d'exécution — des techniques telles que la découpe/le raccordement de circuits peuvent être utilisées. La découpe de circuits est le processus qui consiste à décomposer de grandes tâches quantiques en sous-tâches plus petites et gérables, pouvant être distribuées sur plusieurs puces quantiques, permettant ainsi un calcul quantique scalable malgré les limitations matérielles. Le raccordement de circuits désigne le processus qui suit la découpe — l'étape de post-traitement classique qui « raccommode » ou combine les résultats des sous-circuits plus petits.
Les ordinateurs quantiques n'ont pas de mémoire traditionnelle, au sens d'un stockage persistant et adressable comme la RAM ou la mémoire GPU. Les ressources de calcul classiques disposent de bits discrets stockés en mémoire, permettant de sauvegarder, récupérer et réutiliser des données pendant le calcul. Les ressources quantiques utilisent des qubits qui ne stockent pas la mémoire au sens classique. Au lieu de cela, les qubits existent dans des états quantiques représentant des superpositions de 0 et 1 simultanément, permettant un parallélisme exponentiel dans l'espace des états. Cependant, les états de qubits sont fragiles et ne peuvent pas être clonés ni lus de manière déterministe à des étapes intermédiaires sans effondrer l'état quantique, donc un comportement persistant de type mémoire pendant le calcul n'existe pas. Les qubits doivent être maintenus dans un état cohérent tout au long de l'exécution, et la « mémoire » est essentiellement l'état quantique lui-même. La mémoire classique ne peut être utilisée qu'aux côtés d'un processeur quantique, et non comme mémoire quantique interne. Cela a des implications significatives : les ressources de calcul classiques peuvent librement réutiliser et stocker les résultats intermédiaires ; les ressources quantiques ne peuvent pas le faire sans mesures qui perturbent le calcul.
Connectivité avec l'infrastructure classique
Les QPUs peuvent être connectés à l'infrastructure classique via des réseaux et diverses interfaces de programmation d'application (APIs) qui permettent aux développeurs de logiciels d'interagir avec les QPUs de manière programmatique. Ces APIs sont généralement masquées derrière des kits de développement logiciel (SDKs) et des bibliothèques (comme Qiskit) et exposées aux scientifiques computationnels sous la forme d'abstractions de programmation (comme les Qiskit Primitives, dont nous parlerons dans le Chapitre 3 : modèles de programmation).
Il vaut la peine de distinguer entre l'intégration étroite et lâche des ressources quantiques et classiques. Actuellement, les QPUs ne se trouvent pas sur le même nœud que les ressources de calcul classiques. En fait, les QPUs ne sont pas actuellement connectés via PCIe, mais via le réseau. Cela pourrait changer à l'avenir, mais il existe des défis d'ingénierie liés aux conditions environnementales optimales pour les QPUs et les ressources de calcul classiques.
Mise à l'échelle des ressources quantiques
La mise à l'échelle des ressources quantiques peut également être catégorisée en verticale et horizontale.
- La mise à l'échelle verticale consisterait à augmenter le nombre de qubits par puce ou à améliorer la fidélité des dispositifs.
- La mise à l'échelle horizontale consisterait à connecter des puces avec des coupleurs ou avec une interconnexion classique.
Vérifie ta compréhension
Quels sont les équivalents quantiques des (a) bits d'information classiques, et (b) de la vitesse du processeur ?
Réponse :
(a) Les bits quantiques ou qubits — unités d'information qui, contrairement à leurs homologues classiques (qui ne peuvent prendre que l'état 0 ou 1), peuvent être en une superposition de 0 et 1 simultanément.
(b) Les opérations de couche de circuit par seconde ou CLOPS — le nombre d'opérations séquentielles que le QPU peut effectuer chaque seconde, incluant une certaine interface avec les ressources de calcul classiques, comme lors du chargement des paramètres depuis le circuit.
Gestion des ressources
Les ressources HPC et quantiques sont à la fois précieuses et complexes ; elles doivent être gérées avec soin. Dans cette section, nous allons expliquer comment gérer les ressources pour les programmes utilisateurs. La gestion des ressources dans l'infrastructure de calcul désigne le processus de (1) planification, (2) allocation, et (3) contrôle/gestion de l'utilisation des ressources informatiques telles que les CPUs, la mémoire, le stockage et la bande passante réseau, afin d'assurer une utilisation efficace et efficiente des ressources.
Planification — estimation des ressources
Tout programme consomme des ressources, et estimer les ressources nécessaires est crucial pour une gestion efficace. Cela inclut l'estimation de la quantité de CPU, de mémoire et d'autres ressources nécessaires à l'exécution d'un programme. La même logique s'applique aux ressources quantiques. Cependant, les ressources quantiques existent à une échelle complètement différente. Les processeurs quantiques IBM Quantum® Heron r3 disposent de 156 qubits, contre les nombreux milliards de bits classiques d'un ordinateur portable ordinaire. Le temps et le coût sont également des facteurs à prendre en compte. Actuellement, IBM Quantum propose un plan gratuit, l'Open Plan, qui permet aux utilisateurs d'explorer le calcul quantique en utilisant 10 minutes de temps QPU par mois. Certaines organisations de recherche nécessitent tellement de temps QPU qu'elles disposent d'un ordinateur quantique IBM dédié sur site.
Une étape d'estimation des ressources unique au calcul quantique est la profondeur du circuit. Comme mentionné précédemment, chaque porte quantique et chaque délai entre opérations s'accompagnent de bruit et d'une certaine probabilité d'erreur. Plus le circuit quantique est profond, plus le bruit est important. Il y a deux subtilités à cela : les portes à deux qubits ont des taux d'erreur bien plus élevés que les portes à un qubit, donc on peut souvent ignorer la profondeur à un qubit. De plus, tous les qubits d'une puce quantique ne sont pas directement connectés. Il faut parfois permuter l'information de qubit en qubit pour effectuer les intrications requises, et ce processus de permutation nécessite lui-même des portes à deux qubits. Cette permutation est gérée dans un processus appelé « transpilation », un processus complexe qui sert aussi à d'autres fins ; cela est discuté plus en détail dans la leçon suivante. La quantité limite pertinente est donc la profondeur transpilée à deux qubits. La profondeur maximale exacte à laquelle des résultats de haute fidélité peuvent être obtenus dépend du circuit. Mais en tirant parti des techniques modernes de mitigation d'erreurs, on peut obtenir des résultats de haute fidélité avec des profondeurs transpilées à deux qubits de 80 ou plus.
Allocation — ordonnancement
L'ordonnancement est le processus d'allocation des ressources aux programmes et de gestion de leur exécution. Cela implique :
- Soumission de travaux : Le processus par lequel un utilisateur envoie une requête (travail) au système HPC, en précisant quels calculs et quelles ressources sont nécessaires à l'exécution.
- Allocation des ressources : L'assignation des ressources disponibles du système HPC (telles que les nœuds, CPUs, mémoire) à un travail soumis en fonction de ses besoins.
- Exécution des travaux : L'exécution effective des tâches computationnelles définies par le travail sur les ressources HPC allouées.
Il existe des équivalents de tous ces processus pour les ordinateurs quantiques.
- Les travaux sont soumis par l'utilisateur en exploitant Qiskit Runtime, et utilisent généralement une primitive Qiskit Runtime, comme
Sampler,Estimator, ou d'autres. - L'utilisateur sélectionne parmi une liste de backends auxquels il a accès. La liste complète des backends disponibles peut être consultée sur la page Ressources de calcul d'IBM Quantum Platform. Il est courant d'utiliser simplement l'ordinateur quantique le moins occupé. Mais il peut y avoir des cas où il est important d'en utiliser un spécifique, pour des raisons liées à la disposition du dispositif, à la réplication de calculs précédents, etc.
- L'exécution des travaux quantiques est similaire au cas HPC. Bien que certaines différences aient déjà été soulignées, quelques-unes méritent d'être répétées ici. Les QPUs ne se trouvent généralement pas sur le même nœud que les ressources de calcul classiques, mais sont connectés via un réseau. Cela peut avoir des implications pour l'ordonnancement. De plus, les ordinateurs quantiques peuvent avoir des temps d'attente substantiels, et ces temps varient, rendant difficile un contrôle précis du timing. Cette situation peut être différente pour les systèmes dédiés ; cela dépend de l'administration interne de l'ordinateur quantique.
Contrôle/Gestion — gestion de la charge de travail
La gestion de la charge de travail, également connue sous le nom d'orchestration, est le processus de gestion de plusieurs programmes et de leurs besoins en ressources. Cela implique :
- Provisionnement des ressources : Le processus de préparation et de mise à disposition des ressources HPC pour les travaux, incluant la configuration matérielle et logicielle. Comme nous le verrons plus tard, les QPUs sont des ressources de calcul pouvant être provisionnées de manière similaire aux ressources HPC classiques, avec les mises en garde de la section précédente.
- Ordonnancement des travaux : L'activité du logiciel d'ordonnancement consistant à décider quels travaux s'exécutent, quand et sur quelles ressources, gérant les priorités et les files d'attente pour utiliser efficacement le système HPC. Bien que cette déclaration générale s'applique aux ressources quantiques, il peut y avoir moins de contrôle sur le timing qu'avec d'autres ressources.
Exemple :
Prenons une tâche bien connue comme contexte pour comprendre la gestion des ressources : trouver les facteurs premiers de grands nombres. Supposons de plus que l'algorithme utilisé repose sur la vérification par force brute de chaque diviseur potentiel. Bien que ce ne soit souvent pas la méthode la plus efficace, il est facile de comprendre comment la charge de travail pourrait être gérée.
Planification — estimation des ressources
- Estimer le temps CPU et la mémoire que la factorisation première pourrait nécessiter.
- Planifier la parallélisation de ta tâche — combien de CPUs/cœurs utiliseras-tu ?
Allocation — ordonnancement
- Lors de la soumission du travail, l'ordonnanceur assigne des cœurs CPU et de la mémoire à la tâche de factorisation première. Par exemple, il pourrait allouer tous les diviseurs potentiels se terminant par les chiffres
1, 3, 7, 9à l'un des quatre cœurs, respectivement. - Exécution du travail : L'algorithme de factorisation première s'exécute, effectuant des divisions ou d'autres étapes de factorisation sur les ressources allouées jusqu'à la fin de la tâche.
Contrôle/Gestion — gestion de la charge de travail
- Le système orchestre l'ordre et le timing des travaux de factorisation première pour optimiser le débit.
- Le cas le plus simple à imaginer est que l'un des cœurs trouve le facteur premier cible. Cela devrait arrêter le calcul sur les autres cœurs pour qu'ils puissent être utilisés pour la tâche suivante.
Les environnements de calcul haute performance utilisent des logiciels spéciaux pour effectuer ces étapes et gérer les ressources. Dans la section suivante, nous allons découvrir un système de gestion des ressources largement adopté : Slurm.
Exemple avec des ressources quantiques :
Un flux de travail qui sera l'objet d'autres leçons de ce cours est la détermination des états fondamentaux chimiques et des énergies à l'aide de la diagonalisation quantique par échantillonnage (SQD). Cela est couvert plus en détail dans la Leçon 4, et tu peux également consulter ce cours sur SQD et les méthodes associées sur IBM Quantum Learning. Tout ce que nous devons savoir pour cette discussion, c'est que le flux de travail implique les étapes suivantes :
- Préparer un circuit quantique
- Mesurer le circuit quantique
- Utiliser les résultats des mesures pour projeter le problème dans un sous-espace utile
- Diagonaliser une matrice projetée plus petite en utilisant des ressources de calcul classiques
- Itération, soit pour assurer la cohérence par des considérations comme la conservation de la charge, et éventuellement des itérations du circuit quantique s'il a des paramètres variationnels.
Planification — estimation des ressources
- Mapper les orbitales électroniques sur les qubits pour établir le nombre de qubits nécessaires.
- Combiner l'hamiltonien mappé du système et l'état (éventuellement variationnel) en un circuit quantique et vérifier la profondeur transpilée à deux qubits. S'assurer qu'elle est raisonnable.
- Estimer la taille du sous-espace dans lequel tu vas projeter ; à partir de cela, estimer le temps CPU et la mémoire que la diagonalisation pourrait nécessiter.
- Planifier la parallélisation de ta tâche — combien de CPUs/cœurs utiliseras-tu ?
Allocation — ordonnancement
- L'utilisateur sélectionne le QPU ; le processus de transpilation mappe automatiquement les qubits de ton circuit quantique abstrait sur les qubits physiques du QPU. Ceci est important car le circuit abstrait peut supposer une connectivité directe qui n'existe pas sur la puce, entre autres raisons.
- Lors de la soumission du travail via Qiskit Runtime, le travail entre dans la file d'attente pour le QPU sélectionné. L'utilisateur n'a aucun contrôle sur le temps d'attente, bien que cela puisse être différent pour les systèmes dédiés.
- Les ressources de calcul classiques attendent les résultats quantiques.
- Un travail de diagonalisation est soumis aux ressources HPC ; lors de la soumission du travail, l'ordonnanceur assigne des cœurs CPU et de la mémoire à la tâche de diagonalisation.
- Exécution du travail : L'algorithme de diagonalisation s'exécute, diagonalisant la matrice projetée plus petite jusqu'à la fin de la tâche.
Contrôle/Gestion — gestion de la charge de travail
- Le système orchestre l'ordre et le timing des étapes quantiques et classiques tout au long. Par exemple, une fois la matrice projetée diagonalisée et une énergie d'état fondamental obtenue, selon les critères de convergence, le flux de travail peut revenir à un nouveau circuit quantique (avec un nouveau paramètre variationnel).
- Lorsque les critères de convergence sont satisfaits par l'énergie de l'état fondamental, le calcul sur tous les cœurs s'arrête.
Les environnements de calcul haute performance utilisent des logiciels spéciaux pour effectuer ces étapes et gérer les ressources. Dans la section suivante, nous allons découvrir un système de gestion des ressources largement adopté : Slurm. Il est important de noter que Slurm ne dispose pas d'outils pour toutes les étapes décrites ci-dessus. Slurm ne prend pas en charge la planification des travaux, ni la gestion détaillée de la charge de travail telle que la communication entre les composants de la charge de travail. Cela correspond bien à l'état actuel du calcul quantique dans le HPC, puisque les QPUs sont généralement accessibles via le réseau.
Vérifie ta compréhension
Suppose que tu essaies de rechercher dans une base de données non triée un élément que nous appellerons la « cible ». Pour chacune des actions suivantes, indique à quelle étape de la gestion des ressources elle correspond :
(a) Estimer la taille de la base de données et le temps nécessaire pour vérifier chaque élément
(b) S'assurer que trouver la cible sur un GPU arrête le processus sur les autres GPUs pour les libérer pour le prochain problème.
(c) Diviser l'espace de recherche en régions pour chacun de tes (disons 10) GPUs à explorer
Réponse :
(a) Planification (b) Contrôle/gestion (c) Allocation/ordonnancement,
Logiciel : Slurm
Dans cette section, nous allons appliquer les concepts appris dans ce chapitre pour pratiquer l'utilisation du système de gestion des ressources populaire, Slurm.
Introduction à Slurm
Slurm est un système de gestion des ressources open source largement utilisé dans les environnements de calcul haute performance. Il fournit un ensemble complet d'outils pour gérer les ressources, ordonnancer les travaux et surveiller les performances du système.
Nous aborderons les bases de l'utilisation de Slurm, notamment :
- La soumission de travaux
- L'allocation des ressources
- La surveillance des travaux
Puisqu'il est vraiment difficile de fournir des ressources HPC à chaque étudiant de ce cours, nous allons tricher un peu et te fournir un dépôt avec des images Docker qui imitent un vrai cluster HPC avec Slurm, mais à petite échelle. Cela nous aidera à pratiquer les concepts appris dans des environnements sûrs et reproductibles.
À noter qu'actuellement, toutes les ressources quantiques et classiques sont allouées pour toute la durée de l'expérience. Il n'y a actuellement pas d'allocation entrelacée de ressources mixtes. Une dernière mise en garde : même une fois le travail lancé, le système quantique ne sera pas directement contrôlé comme un utilisateur HPC chevronné pourrait s'y attendre. Le travail est lancé sur un nœud x86 arbitraire, qui exécute le service Qiskit Runtime, et ce service d'exécution se connecte à un autre ordonnanceur sur lequel l'utilisateur n'a aucun contrôle direct. Ce flux de travail et les problèmes associés peuvent être connus des utilisateurs HPC qui ont eu une expérience précoce dans la recherche d'un accès exclusif aux nœuds GPU (utilisation originale de gres).
Instructions d'installation et aperçu de la configuration
Pour pratiquer la combinaison des ressources quantiques et HPC, tu auras besoin soit d'accès à un vrai environnement HPC, soit de simuler un environnement HPC sur ta machine locale. Un guide d'installation pour la configuration locale avec Docker peut être trouvé dans ce dépôt. Le guide renvoie vers de l'aide pour créer un compte IBM Cloud® et installer le plugin SPANK pour QRMI. Dans ce dépôt se trouvent également plusieurs fichiers Python pour tester ton environnement.
Une fois l'installation terminée, utilisons la commande ci-dessous pour vérifier les ressources de calcul de Slurm dans ton terminal. Si l'installation a réussi, tu devrais pouvoir confirmer un total de trois nœuds virtuels.
$ sinfo
PARTITION AVAIL TIMELIMIT NODES STATE NODELIST
normal up 5-00:00:00 2 idle c[1-2]
quantum* up infinite 1 idle q1
$ scontrol show node
NodeNAME=q1 Arch=x86_64 CoresPerSocket=1
CPUAlloc=0 CPUTot=1 CPULoad=0.34
AvailableFeatures=(null)
ActiveFeatures=(null)
Gres=qpu:1
NodeAddr=q1 NodeHostName=q1 Version=21.08.6
...
Nous avons deux partitions ou groupes de nœuds : normal et quantum. La partition normal est composée de nœuds ayant accès uniquement aux ressources classiques. La partition quantum a accès aux ressources quantiques. Tu peux voir les détails de chaque nœud en exécutant scontrol show nodes.
Exécuter un simple exemple hello world dans Slurm
Commençons par exécuter un simple exemple hello world classique avec Slurm. Nous utiliserons Python pour les exemples. Créons hello_world.py, qui est explicite.
$ vim hello_world.py
import time
time.sleep(10)
print("Hello, World!")
~
Nous devons maintenant indiquer au gestionnaire de ressources quelles ressources nous avons besoin pour exécuter ce programme. Slurm fournit un moyen de spécifier toutes les métadonnées du travail via un script de soumission, qui est simplement un script shell avec des annotations spécifiques à Slurm. Ces annotations te permettent de spécifier les besoins en ressources, les paramètres d'ordonnancement, etc. Créons un script shell hello_world.sh pour cela.
$ vim hello_world.sh
#SBATCH --job-name=hello-world
#SBATCH --output=hello-world.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=normal
srun hello_world.py
~
Passons en revue le fichier de soumission et voyons ce qui se passe ici.
Les directives #SBATCH sont des annotations spécifiques indiquant nos besoins pour l'exécution du programme. Tu peux y spécifier la quantité de ressources — le nombre de nœuds, le nombre de tâches par nœud, le nombre de tâches et de CPUs par nœud et par tâche — et d'autres options comme le nom du fichier de sortie. La liste complète des options est disponible dans la documentation de Slurm.
Il est maintenant temps d'exécuter notre travail Slurm. sbatch est une commande qui accepte un fichier de soumission et met le travail en file d'attente pour exécution dans Slurm.
$ sbatch hello_world.sh
Submitted batch job 63
Vérifions le statut de notre programme avec la commande squeue.
$ squeue
# JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
# 1 main hello_world root R 0:01 1 c1
Une fois le travail terminé, nous pouvons vérifier le résultat en consultant le fichier de sortie.
$ cat hello_world_logs.txt
Hello, World!
Vérifie ta compréhension
Étant donné le script shell Slurm ci-dessous, quel est (a) le nom du travail, (b) le nom du fichier Python, et (c) le nom du fichier de sortie ? (d) Enfin, ce script pourrait-il utiliser des ressources quantiques ou non ?
vim hello_learner.sh
#SBATCH --job-name=hello-learner
#SBATCH --output=hello-learner.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum
srun hello_learner_qm.py
vim hello_learner.sh
#SBATCH --job-name=hello-learner
#SBATCH --output=hello-learner.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum
srun hello_learner_qm.py
Réponse :
(a) hello-learner (b) hello-learner_qm.py (c) hello-learner.out (d) Oui, il le pourrait. Il utilise la partition quantum.
Exécuter un simple exemple Qiskit hello world dans Slurm
Ensuite, essayons d'utiliser aussi des ressources quantiques. Créons et exécutons un simple programme « Hello, Qiskit » qui utilise des ressources quantiques.
$ vim hello_qiskit.py
# hello_qiskit.py
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import EstimatorV2 as Estimator
# Create a new circuit with two qubits
qc = QuantumCircuit(2)
# Add a Hadamard gate to qubit 0
qc.h(0)
# Perform a controlled-X gate on qubit 1, controlled by qubit 0
qc.cx(0, 1)
observables_labels = ["IZ", "IX", "ZI", "XI", "ZZ", "XX"]
observables = [SparsePauliOp(label) for label in observables_labels]
# switch to QRMI service
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend = service.backend("...")
# Convert to an ISA circuit and layout-mapped observables.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
# Construct the Estimator instance.
estimator = Estimator(mode=backend)
estimator.options.resilience_level = 1
estimator.options.default_shots = 5000
mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]
# One pub, with one circuit to run against five different observables.
job = estimator.run([(isa_circuit, mapped_observables)])
job_result = job.result()
pub_result = job.result()[0]
print("Result", pub_result)
Ici nous utiliserons l'interface de gestion des ressources quantiques (QRMI), un plugin SPANK pour Slurm destiné à la prise en charge des ressources et travaux quantiques, développé conjointement par IBM, Pasqal, The Hartree Center et RPI. Nous avons créé un simple circuit pauli-2-design avec des valeurs initiales aléatoires et un observable simple, et nous allons l'exécuter avec Estimator pour obtenir la valeur d'espérance. Pour l'exécuter, nous aurons à nouveau besoin du script de soumission hello_qiskit.sh, qui aura les ressources quantiques comme exigence.
$ vim hello_qiskit.sh
#SBATCH --job-name=hello-qiskit
#SBATCH --output=hello_qiskit.out
#SBATCH --nodes=1
#SBATCH --ntasks-per-nodes=1
#SBATCH --cpus-per-task=1
#SBATCH --partition=quantum
#SBATCH --gres=qpu:1
srun python /data/ch2/hello_qiskit/hello_qiskit.py
~
Examinons le fichier de soumission et voyons ce qui s'y passe. Nous avons une nouvelle option, gres. gres est une option Slurm pour définir des ressources computationnelles supplémentaires. Dans notre cas, cette nouvelle ressource serait notre ressource quantique. Puisque nous avons spécifié les ressources et la partition de notre cluster où les ressources quantiques sont disponibles, nos primitives Qiskit utiliseront ces ressources allouées pour exécuter la charge utile quantique.
Il est maintenant temps d'exécuter notre travail Slurm.
$ sbatch hello_qiskit.sh
Ensuite, vérifions le statut de notre programme avec la commande squeue.
$ squeue
# JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
# 1 main hello_qiskit root R 0:01 1 q1
Nous pouvons explorer les journaux et les résultats après la fin du travail.
$ cat hello_qiskit.out | grep Exp
Expectation Value: 0.8372900070983516
Résumé
Jusqu'à présent, nous avons appris ce que sont les ressources computationnelles et comment les utiliser pour exécuter des programmes dans des environnements hétérogènes. Nous avons également créé et exécuté deux simples programmes « Hello World » : l'un pour la ressource classique et l'autre pour une ressource quantique, et nous avons appris à créer des scripts shell pour soumettre des tâches et consulter les résultats.
Dans la leçon suivante, nous nous appuierons sur ces connaissances du contrôle des ressources pour appliquer des modèles de programmation aux ressources que nous avons acquises lors de l'exécution des travaux.
Tout le code et les scripts utilisés dans ce chapitre sont disponibles dans notre dépôt GitHub.