• Aucun résultat trouvé

C permet une composition via l’appel de procédures natives C++, l’appel de procédure à distance via CORBA, et le passage de messages via MPI. Tout comme CCA, les composants L2

C fournissent des services par le biais de ports provide, en utilisent d’autres par le biais de ports use, et la communication entre les instances de composants consiste à appeler des procédures sur les ports. Les services doivent être déclarés en tant que classe abstraite C++ ou interface CORBA. L2

C fournit aussi des ports MPI qui permettent aux instances de composants de partager des communicateurs MPI. Les composants peuvent aussi exposer des attributs utilisés pour configurer les instances. En pratique, les composants L2

C sont des classes C++ auxquelles sont ajoutées des annotations nécessaires à la déclaration de composants (p. ex. nom, ports et propriétés).

Un assemblage L2

C peut être décrit en utilisant un fichier de description d’assem-blage en XML (LAD) dont la spécification (schéma XML) est donnée en annexeB.6 (page174). Ce fichier contient la description de toutes les instances de composants, leur configuration et les connexions entre les instances (use-provide et MPI). Chaque instance de composant est attachée à un processus et à chaque processus est associé à un point d’entrée (une interface sollicitée au démarrage de l’application).

2.5.3 Conclusion

Dans cette section, nous avons vu qu’il existe plusieurs méthodes permettant de composer des codes parallèles : la composition use-provide parallèle, le partage de données, les flux de données et de travaux, les squelettes algorithmiques ainsi que les connecteurs MPI.

L’usage d’une méthode plutôt qu’une autre dépend des codes à composer : le paradigme de programmation utilisé, les propriétés intrinsèques aux codes composés telles que la présence d’un état persistant nécessaire pour réaliser les traitements ainsi que la simplicité à adapter les codes afin qu’ils puissent interagir ensemble à travers la méthode de composition ciblée.

Il est important de noter que la majeure partie des méthodes de composition existantes présentées dans la section précédente font des hypothèses sur le paradigme de programmation des codes composés : les codes parallèles doivent utiliser soit des fils d’exécution tels que des processus MPI (principalement dans le cas de la composition use-provide ou de données partagées), soit des tâches persistantes qui interagissent par le biais de flux de données.

Dans une dernière partie, cette section a décrit L2

C, un modèle de composants dédié au calcul de haute performance qui est utilisé dans les chapitres 3et 4.

2.6 Discussion

Cette section reprend les éléments et principes présentés dans les sections précé-dentes (c.-à-d. les sections 2.1, 2.2, 2.3, 2.4 et 2.5) afin de motiver et d’énoncer les objectifs de cette thèse.

2.6.1 Analyse

Dans la section 2.1, nous avons vu que les supercalculateurs d’aujourd’hui sont complexes et leur amélioration continue n’a pas cessé d’accroître leur complexité au fils des années, notamment par l’intégration de nouvelles formes de parallélisme, de hiérarchies de caches plus profondes, ou encore de systèmes de prédiction probabi-liste. Exploiter efficacement ces architectures matérielles s’avère difficile. Alors que l’usage de systèmes NUMA et d’accélérateurs de calcul tend à se démocratiser [71,

74], programmer des applications numériques (telles que celles visant à résoudre des équations différentielles partielles) sur de ces architectures matérielles est aujour-d’hui un véritable défi sans l’aide d’un paradigme de programmation adapté.

Ce fardeau devient quasiment insurmontable dans le cas où les concepteurs tentent de considérer d’autres critères tels que le support de plusieurs types d’archi-tectures (p. ex. code ciblant les CPU et GPU) et la maintenabilité de l’application (problème évoqué dans la section 2.2).

Dans la section 2.3, nous avons vu que l’ordonnancement de graphes de tâches est une approche prometteuse visant à pallier les problèmes d’exploitation des ar-chitectures matérielles complexes et la portabilité des performances des codes HPC sur diverses architectures matérielles. Néanmoins, cette approche ne prend pas en compte les aspects liés à la maintenance des applications énoncés dans la section2.4. Les modèles de composants (présentés dans les sections2.4 et2.5) possèdent des propriétés qui favorisent la conception d’applications maintenables. De ce fait, une utilisation combinée des modèles de composants et de l’ordonnancement de graphes de tâches pourrait donc être manifestement bénéfique pour les applications HPC. Une telle combinaison apporterait un nouveau moyen de composer des codes HPC. L’avantage majeur de cette forme de composition serait de permettre une exploi-tation efficace des ressources matérielles utilisées par les codes composés. Idéalement, cette forme de composition devrait être capable de combiner des codes HPC à base de tâches sans occasionner de sérialisation, synchronisation ou communication arti-ficielle.

L’approche de composition existante la plus proche pour effectuer une telle opé-ration consiste à utiliser des flux de données entre des composants. Cependant, les approches existantes imposent généralement une sérialisation du flux. De plus, comme nous l’avons évoqué précédemment, cette forme de composition ne convient pas à tous les usages. En particulier, elle s’avère être peu appropriée à l’échelle de l’ensemble du code Gysela, actuellement divisé en modules impératifs constitués d’un ensemble de fonctions interdépendantes (de granularité variable) partagées entre les modules. Dans ce dernier cas, la composition use-provide se révèle être particulière-ment bien adaptée.

À notre connaissance, aucun modèle de composants existant n’offre toutes ces propriétés.

2.7. CONCLUSION 49

2.6.2 Objectifs et approche

Dans ce manuscrit, nous nous intéressons tout particulièrement à la composition de codes parallèles qui visent à produire un graphe de tâches. L’un des objectifs majeurs de cette approche est de pouvoir composer deux codes parallèles, qui seuls, exploitent efficacement les ressources à disposition et dont la composition engendre une exécution utilisant pleinement toutes les ressources nécessaires. Par exemple, en composant un code limité par la mémoire avec un code de calcul intensif, il est possible d’engendrer un code plus efficace que si chaque code est considéré indé-pendamment, notamment en régulant l’utilisation de la mémoire par l’exécution de tâches de calcul intensif (évitant ainsi la saturation d’une ressource partagée).

Dans les sections 2.2 et 2.3, nous avons vu que les applications HPC exploitent massivement le parallélisme de données afin de pouvoir passer à l’échelle. Pour cela, les applications HPC partitionnent généralement les données traitées. De plus, nous avons pu voir que bon nombre de supports exécutifs d’ordonnancement de graphes de tâches permettent de porter des dépendances entre les tâches par le biais de données. Ainsi, offrir des mécanismes de composition de codes HPC centrés sur des données pouvant être partitionnées semble être une bonne direction de recherche pour aborder ce problème.

Notre objectif est donc d’étudier la faisabilité d’une méthode de composition de codes parallèles à base de tâches préservant les propriétés suivantes :

— deux codes efficaces composés ensemble doivent être au moins aussi efficaces (c.-à-d. utilisation efficace des ressources après composition) ;

— deux codes ayant recours à des distributions de données différentes doivent être facilement composés sans introduire de synchronisations artificielles (c.-à-d. indépendance des codes composés et présence de mécanisme de redistribution des données entre les codes) ;

— une exécution entrelacée des codes parallèles doit être possible avec de faibles surcoûts (c.-à-d. composition de codes à grain fin).

2.7 Conclusion

Ce chapitre a présenté en six sections le contexte et l’état de l’art de la thèse qui se concentrent sur le calcul de haute performance et la composition de code parallèle à travers l’utilisation de modèles de composants.

Pour cela, la première section a étudié les architectures matérielles pour le cal-cul de haute performance. Cette section a montré en partical-culier leur complexité et leur variabilité ainsi que leur capacité à pouvoir exécuter des codes massivement parallèles en mettant en œuvre différentes formes de parallélisme.

La seconde section de ce chapitre a analysé les applications HPC s’exécutant tout naturellement sur les architectures matérielles présentées avant. Elle s’est concen-trée plus particulièrement sur le cas de l’application de physique des plasmas par confinement magnétique pour la fusion Gysela, dont des sous-parties sont étudiées dans ce manuscrit. Cette section a fait ressortir plus spécifiquement les compromis

réalisés dans Gysela liant les performances du code à sa maintenabilité.

La troisième section a présenté les catégories de paradigmes de programmation les plus utilisés pour programmer des applications HPC. Elle a mis en évidence la va-riabilité des modèles de programmation existants et leurs singularités. Cette section a présenté plus particulièrement les approches à base de graphe de tâches particu-lièrement utiles pour utiliser efficacement les ressources de calcul des plateformes HPC ainsi que pour s’abstraire de la variabilité du matériel.

La quatrième section s’est concentrée sur la conception des applications HPC et plus précisément sur la structuration des codes HPC et les interactions qui lient les différentes parties d’une même application. Elle a présenté les approches à base de composants logiciels et a décrit les méthodes pouvant être employées pour composer des codes indépendamment de la présence du parallélisme en leur sein.

La cinquième section a décrit plus précisément les méthodes existantes permet-tant de composer des codes HPC. Elle a souligné que l’usage d’une méthode de composition plutôt qu’une autre dépend des codes à composer, en particulier du paradigme de programmation utilisé dans les codes composés.

Enfin, la dernière section a repris l’ensemble du contexte et de l’état de l’art exposé dans ce manuscrit afin d’évoquer les motivations de cette thèse ainsi que ces objectifs. En particulier, elle s’est intéressée au cas de la composition de codes paral-lèles utilisant des approches à base de graphes de tâches qui, à notre connaissance, n’est pas traitée dans les modèles de composants existants.

Le chapitre suivant présente Comet, un modèle de composants pour le calcul de haute performance supportant l’ordonnancement de graphes de tâches et offrant des mécanismes pour la composition de ces graphes de tâches.

Chapitre 3

Le modèle Comet

Contents

2.1 Plateformes . . . 7 2.1.1 Aperçu . . . 8 2.1.2 Architectures à mémoire partagée. . . 9 2.1.3 Architectures à mémoire distribuée . . . 14 2.1.4 Conclusion . . . 14 2.2 Applications. . . 15 2.2.1 Conception et analyse d’applications parallèles . . . 15 2.2.2 Domaines applicatifs . . . 16 2.2.3 Équations aux dérivées partielles . . . 17 2.2.4 Conception et maintenance . . . 18 2.2.5 Focus : Gysela . . . 18 2.2.6 Conclusion . . . 22 2.3 Paradigmes et modèles de programmation . . . 22 2.3.1 Parallélisme de données et de tâches . . . 22 2.3.2 Interaction : mémoire partagée et passage de messages . . 24 2.3.3 Modèles de programmation parallèle . . . 25 2.3.4 Conclusion . . . 32 2.4 Programmation par composition . . . 32 2.4.1 De la programmation structurée aux modèles de composants 32 2.4.2 Définitions . . . 35 2.4.3 Concepts . . . 38 2.4.4 Formes de composition. . . 39 2.4.5 Conclusion . . . 41 2.5 Programmation parallèle par composition . . . 42 2.5.1 Forme de composition de codes parallèles . . . 42 2.5.2 L2

C : un modèle de composants minimaliste pour le HPC 46 2.5.3 Conclusion . . . 47 2.6 Discussion . . . 47

2.6.1 Analyse . . . 48 2.6.2 Objectifs et approche. . . 49 2.7 Conclusion. . . 49

Cette section présente une des contributions de la thèse : un modèle à composant avec support de l’ordonnancement de tâches. La section 3.1 donne un aperçu du modèle Comet et de sa structure. La section 3.2 présente les entités fondamentales de Comet. La section3.3montre comment construire une application en composant les entités fondamentales du modèle. Enfin, la section 3.5 conclut ce chapitre.

3.1 Aperçu

Cometest un modèle de composants dédié au calcul haute performance et sup-portant l’ordonnancement de graphes de tâches. Il vise à assembler simplement des codes parallèles indépendants tout en permettant une exécution efficace. Pour cela, Comet se base sur le modèle de composants existant L2

C qui supporte la compo-sition use-provide et MPI. Il l’étend en supportant une nouvelle forme d’interaction entre les composants à base de flux de données manipulant des données partitionnées ainsi qu’en ajustant les ports use-provide. Cette extension permet de construire un graphe de tâches en composant successivement des morceaux de graphe de tâches.

Cometcible en particulier les architectures à mémoire partagée. Néanmoins, il supporte aussi les architectures à mémoire distribuée en se basant sur MPI pour la communication entre les nœuds de calcul.