L’approche Model Driven Architecture de l’OMG

Télécharger le fichier pdf d’un mémoire de fin d’études

Évolution des architectures

À présent, nous allons retracer rapidement l’évolution des supercalculateurs et de leurs architectures matérielles. Bien que le passé ne préjuge pas de l’avenir, l’objectif de cette par-tie est de montrer que des changements sont apparus par le passé et que face aux challenges actuels la probabilité pour que l’avenir nous réserve des changements bien plus radicaux est très grande. Nous terminerons cette section par la présentation des architectures qui pourraient devenir courantes dans un futur plus ou moins proche.
Origine
L’automatisation du calcul scientifique fut la motivation première des pionniers de l’informatique. L’ouverture de l’informatique à d’autres domaines d’applications ne fut en effet que bien plus tardive.
En 1834 le mathématicien anglais Charles Babbage débute la conception d’une cal-culatrice programmable : l’Analytical Engine. Cette dernière, entièrement mécanique, ne sera malheureusement jamais terminée de son vivant. Il faudra attendre 1942 pour voir apparaitre le premier calculateur électronique : l’ABC (Atanasoff Berry Computer). Cette machine, capable de réaliser 30 additions en parallèle, n’était par contre pas programmable.
Le premier ordinateur commercial scientifique avec virgule flottante, l’IBM 704, appa-rait aux États-Unis en 1955. C’est pour cet ordinateur que les langages de programmation Fortran et LISP ont initialement été développés. Cependant, on considère généralement que l’ère des supercalculateurs a débuté dans le courant des années soixante avec la mise sur le marché de l’IBM 7030 et du célèbre CDC 6600 dont l’architecte était Seymour Cray [198] (cf. figure 2.10). Le CDC 6600 restera le supercalculateur le plus puissant au monde pendant cinq ans. Son successeur, le CDC 7600, qui était dix fois plus puissant connaitra le même sort et restera numéro un pendant cinq ans.
Révolution vectorielle : l’ère Cray
Suite à des divergences d’opinions avec sa hiérarchie, Cray quitte CDC en 1972 pour fonder sa propre compagnie : Cray Research. Quatre ans plus tard, il met sur le marché le légendaire Cray-1, devenu l’un des plus grands succès de l’histoire des supercalculateurs [121] (cf. figure 2.11).
C’est le début d’une nouvelle ère, celle des architectures vectorielles. Ce type d’architec-ture propose des jeux d’instructions permettant de manipuler directement des vecteurs. La figure 2.12 compare les opérations nécessaires pour réaliser une addition de deux vecteurs A et B de taille 10 sur un processeur scalaire et sur un processeur vectoriel. L’implémentation des architectures vectorielles repose sur le principe du pipelining. À l’image du travail à la chaine imaginé par Henry Ford, le travail est découpé en étapes élémentaires qui peuvent être réalisées en parallèle.

Langages et outils

Bien qu’elle n’ait pas la prétention d’être exhaustive, cette section présente un large panel de langages et bibliothèques utilisés pour le développement d’applications de calcul scientifique parallèle. Nous verrons que l’expression du parallélisme revêt plusieurs formes. C’est pourquoi nous choisissons le terme « solution logicielle » comme dénominateur com-mun à toutes les formes possibles : langages, bibliothèques, directives de compilation, lan-gage dédié embarqué, etc.
Cette section a pour objectif de relever les forces et faiblesses de chacune de ces so-lutions logicielles vis-à-vis de notre problématique. Afin de mettre en avant les catégories de problèmes les plus récurrents, nous avons défini cinq propriétés : la séparations des préoccupations, la validation, la portabilité, l’abstraction et l’accessibilité, et finalement l’aspect communauté et outils. La complétude de chaque propriété sera notée de 1 (faible) à 3 (forte) en fonction des critères définis en annexe A.

Fortran : l’origine

Le langage Fortran, abbréviation de FORmula TRANslator [56], possède des origines qui se confondent avec celles des supercalculateurs. C’est en effet pour faciliter la program-mation de l’IBM 704 (voir section 2.2.2) que J. Backus proposa un langage de plus haut niveau que les traditionnels langages assembleur utilisés à cette époque. Il décrivait alors Fortran comme étant un système de programmation automatique [16]. La définition de la programmation automatique a évolué au cours du temps mais D. Parnas avec un brin d’humour la synthétise ainsi : « Automatic programming always has been a euphemism for programming with a higher-level language than was then available to the programmer »

Parnas 

Depuis plus d’un demi-siècle, le langage Fortran est la référence de la communauté scien-tifique pour le développement d’application de simulation numérique [84]. De son succès et de son ancienneté découlent une collection impressionnante de bibliothèques dédiées au calcul numérique. Dans le cas du Fortran 90 qui reste la version la plus utilisée, nous avons affaire à un langage procédural qui offre pour les besoins du calcul numérique, des fonctions intrinsèques permettant de manipuler simplement des vecteurs et des matrices. Les premières versions ont su s’adapter d’elles mêmes aux deux premières périodes présen-tées dans la section 2.2.2. Dans le cas des deux dernières périodes (ère multiprocesseur et ère multicœur), il est nécessaire de faire appel à des bibliothèques externes dont certaines seront présentées par la suite.
Bibliothèque de fonctions métiers
Les logiciels de simulation numérique sont composés de certaines briques de base comme la résolution de systèmes linéaires, l’intégration de fonctions ou l’application de transformés de Fourier. Des bibliothèques regroupant des fonctions optimisées permettant d’accomplir ce type de tâche sont légion : LAPACK [12], PLAPACK [207], FFTW [92], MKL [3], NAG [171], Hypre [82], PETSc [17]. C’est d’ailleurs une des forces du langage Fortran qui en compte une grande quantité. À ce stade, il faut néanmoins noter que le couple C /C++ possède aussi un grand nombre de ce type de bibliothèques et que le C++ gagne en importance dans la communauté scientifique. Nous pourrons d’ailleurs constater ce phénomène dans la suite de ce chapitre puisqu’un grand nombre de solutions logicielles sont compatibles avec ou basées sur le langage C++.
Une des solutions pour commencer la parallélisation d’un code de simulation est d’uti-liser les versions parallèles de ce type de bibliothèque. Le parallélisme est alors exprimé au sein de ces bibliothèques grâce aux solutions logicielles que nous présentons dans la suite du chapitre. Pour ces raisons, ces bibliothèques ne sont donc compatibles qu’avec certaines classes d’architectures. Cette approche possède un certain nombre d’avantages et d’inconvénients :
+ les bibliothèques ont l’avantage d’abstraire les technologies sous-jacentes et enlève ainsi à l’utilisateur le besoin de se former sur de nouvelles solutions logicielles. Par conséquent, un développeur peut rapidement paralléliser son code sur une architec-ture dont il ne maitrise pas les subtilités.
+ les bibliothèques sont souvent développées par des experts des méthodes contenues dans ces bibliothèques. Ils ont donc la capacité de produire du code très optimisé ; chaque bibliothèque possède ses propres structures de données. Il faut donc soit ajou-ter une étape de conversion des données avant l’appel à la bibliothèque, soit utiliser la structure de données de la bibliothèque dans tout le programme. Même si la seconde solution semble préférable, deux problèmes sont présents. Dans le cas où plusieurs bibliothèques sont utilisées, on ne pourra passer outre les étapes de conversion des données. Deuxièmement, l’utilisation de la structure de données d’une bibliothèque posera des problèmes lorsque l’on souhaitera essayer une autre bibliothèque ou tout simplement porter l’application sur une autre architecture matérielle ; ce type d’approche ne permet qu’une parallélisation locale à une étape de la simu-lation.
En résumé l’utilisation de bibliothèques de fonctions métiers est utile pour paralléliser une partie spécifique d’un code de simulation mais ne fournit pas d’approche globale de parallélisation.

Initiative HPCS du DARPA

C’est en 2002 que l’agence américaine DARPA (Defense Advanced Research Projects Agency) lança un projet de grande envergure, le High Productivity Computing Systems (HPCS) [73]. L’objectif du projet est d’améliorer la productivité de la communauté du calcul haute-performance dans le but de servir les intérêts de la sureté nationale et des grands groupes industriels américains. Dans le cadre de ce projet, la productivité fut définie comme étant une combinaison de la performance, de la programmabilité, de la portabilité et finalement de la robustesse. Lors de la création du projet il était reconnu qu’un frein majeur à l’adoption à grande échelle de la simulation numérique était la complexité des développements logiciels visant à exploiter la puissance des machines de l’époque. Afin d’améliorer la productivité de ces systèmes de calcul, trois constructeurs de calculateurs (Cray, IBM et Sun) se sont penchés dans le cadre de ce projet autant sur les aspects matériels que logiciels en définissant de nouveaux langages parallèles. Le projet Fortress [11] de la société Sun n’ayant pas été retenu pour la dernière phase du projet HPCS, nous nous concentrerons ici sur les projets de ses deux concurrents : Chapel de Cray et X10 d’IBM.
L’ensemble de ces langages est basé sur le modèle Asynchronous Partitioned Global Address Space (APGAS ) [184] qui est une extension du modèle PGAS présenté en section 3.1.5. Le modèle APGAS fournit un modèle d’exécution plus riche que le modèle SPMD que l’on retrouve généralement dans les langages de type PGAS. On retrouve la notion d’asynchronisme avec la possibilité d’exécuter plusieurs tâches simultanément sur une par-tition de mémoire partagée (dénommée place en X10 et locale en Chapel) alors qu’il n’y a qu’un seul processus par partition mémoire dans le modèle PGAS. De plus, un processus peut invoquer l’exécution d’une tâche sur une partition de mémoire partagée autre que la sienne.
Chapel
Bien que sa syntaxe hérite de langage tel C, Fortran, Java ou Ada ; le langage Chapel [49] n’est une extension d’aucun de ces langages et possède ses propres constructions, syntaxe et sémantique. Les développeurs de chez Cray pensent que l’utilisation d’un langage séquentiel comme base pour la conception d’un langage parallèle mènerait à la confusion et encouragerait un style de programmation séquentiel [213]. Les concepts du langage Chapel sont inspirés du langage HPF (voir section 3.1.4) et du langage ZPL [51] sur lequel ont travaillé de nombreux développeurs de Chapel.
X10
Le nom du langage X10 [54] provient du souhait de ses développeurs de mettre au point un langage parallèle dix fois plus productif (selon la définition de la productivité fournie en début de chapitre) que les langages et bibliothèques qui étaient les plus utilisés
à l’époque. Contrairement au langage Chapel [49], le langage X10 n’a pas été conçu en partant de zéro puisqu’il est une extension du langage Java. Le choix du langage Java par les développeurs d’IBM fut un choix pragmatique. En effet, c’est un langage orienté objet répandu qui possède tout un écosystème logiciel, bibliothèques et outils, dont certains sont développés par IBM.

Assemblage de composants parallèles

Le développement de logiciels de simulation numérique est un domaine où la réutili-sation de code est fréquente. En effet les opportunités sont nombreuses : rénovation d’un code, développement d’un code multiphysique, partage entre différentes équipes, etc. C’est face à ce constat, que des travaux prônant l’utilisation de composants logiciels pour le calcul haute-performance sont apparus [10, 24, 37].
Common Component Architecture (CCA)
Le Common Component Architecture [10] est une spécification de modèle de composant visant à définir la meilleure façon d’appliquer les principes de la programmation orientée composant au domaine du calcul scientifique. CCA définit trois concepts fondamentaux : component, port, framework.
– Les components sont des briques logicielles fonctionnant comme des boites noires. Ils cachent leur complexité interne et n’exposent que des interfaces clairement définies.
– Les ports sont les interfaces abstraites au travers desquelles interagissent les com-ponents. Il existent deux types de port, ceux qui implémentent une fonctionnalité (provides ports) et ceux qui utilisent une fonctionnalité (uses ports).
– Les frameworks ont la charge de gérer l’assemblage et l’exécution d’applications construites à partir de components. Ils sont notamment responsables de connecter les uses ports et provides ports entre eux.
CCA n’étant qu’une spécification, on trouve plusieurs frameworks tel que Ccaffeine [9] et SCIRun2 [215] qui l’implémentent.
Une des forces de l’approche CCA réside dans sa capacité à combiner des composants écrits dans des langages de programmation différents. Deux éléments permettent la réali-sation d’un tel objectif. Tout d’abord les interfaces des composants sont décrites à l’aide d’un langage unique, le Scientific Interface Definition Language [80]. Ensuite, à partir de cette description, l’outil interopérabilité de langage Babel [78] génère le code intermédiaire permettant au fournisseur et à l’utilisateur de l’interface de communiquer.
L’inconvénient majeur de CCA est qu’il ne fournit rien au delà de l’assemblage des composants. Rien n’est dit sur le contenu des composants. Ils doivent donc toujours dé-pendre d’une solution logicielle classique tel que MPI pour la description de leur algorithme parallèle.
High Level Component Model (HLCM)
HLCM [37] est un modèle de composants logiciels qui a pour particularité d’accepter l’ajout d’opérateurs de composition (assemblage de composants) sans modification du mo-dèle. Les modèles HLCM étant abstraits, une phase de spécialisation est nécessaire. C’est grâce à une approche basée sur l’ingénierie dirigée par les modèles, que les modèles HLCM sont spécialisés vers des modèles de composants existants tel que CCA présenté dans la section précédente. Il existe un prototype de mise en œuvre de HLCM appelé HLCM/CCM, qui s’appuie sur le modèle de composant de CORBA [107].
Bien qu’HLCM facilite une bonne structuration des applications ainsi que la réutilisation de composants, il hérite de certaines faiblesses des modèles de composants sur lesquels il s’appuie. Comme nous venons de le voir pour CCA, rien n’est proposé pour le développe-ment interne des composants. Dans ces conditions, comment définir un composant capable de s’exécuter aussi bien sur une architecture de type CPU que sur une architecture de type GPU ? La réutilisation et la portabilité ont donc leur limite avec cette approche.

Accélérateurs matériels

Comme nous l’avons vu dans la section 2.2.2, les accélérateurs sont plébiscités. Leur performance et leur consommation électrique expliquent cet engouement. Cependant, nous allons voir dans cette section que la situation n’est pas aussi idyllique du côté des solutions logicielles permettant de les exploiter.
Compute Unified Device Architecture (CUDA)
Le langage CUDA [132, 183] est une extension du langage C qui est développé par le constructeur de cartes graphiques NVIDIA afin d’exploiter la puissance de calcul de ses GPU. Le langage CUDA permet d’exprimer le parallélisme de données d’une application via l’utilisation d’un grand nombre (de l’ordre de la centaine) de processus très légers.
Dans le modèle de programmation CUDA, on retrouve le concept d’Host qui fait réfé-rence au CPU et le concept de Device qui fait référence au GPU. Le langage CUDA permet de décrire des fonctions (tâches élémentaires) appelées kernels pouvant être exécutées par des devices. C’est l’host qui va déléguer l’exécution des kernels vers les différents devices dispo-nibles sur le système. Une fois que les données ont été transférées vers le device concerné, le kernel va être exécuté par un groupe de processus. Il existe une hiérarchie dans les pro-cessus et leur mémoire qui découle directement de l’architecture matérielle (voir section 2.2.2 et notamment la figure 2.15). Les processus sont regroupés en bloc (thread blocks qui sont alignés sur les streaming multiprocessors) au sein desquels ils peuvent se synchroniser et communiquer par le biais d’une mémoire partagée. Au final on retrouve trois niveaux de mémoire à gérer : processus, bloc et device.
Le langage CUDA possède donc un modèle de bas niveau qui demande beaucoup d’efforts de la part du programmeur pour obtenir d’excellentes performances. Cette faiblesse ne l’a cependant pas empêché de connaitre un certain engouement au cours des dernières années [2]. Bien que le langage CUDA soit spécialement développé pour les GPU NVIDIA, des projets de recherche tentent d’exécuter du code CUDA sur d’autres architectures [169]. Il existe entre autre le projet Ocelot [67] qui vise les GPU du constructeur AMD et les processeurs de type x86.
OpenCL
Le standard OpenCL [131, 196], promu par le consortium Khronos Group, se compose d’un langage portable de bas niveau dérivé du langage C permettant d’écrire des noyaux de calcul pour accélérateurs (kernels) ainsi que d’une interface de programmation permettant de gérer le lancement des kernels sur les accélérateurs. Même si le standard OpenCL partage une partie de son modèle de programmation avec le langage propriétaire CUDA, ses objectifs sont tout autres. En effet le standard OpenCL vise la portabilité. Par conséquent, les devices cibles peuvent être de nature très différente : GPU de différents constructeurs (AMD, NVIDIA, VIA), processeurs multicœurs, processeurs Cell BE, etc.
Malheureusement la promotion d’une interface standard de bas niveau possède son lot d’inconvénients. Tout d’abord, elle empêche les constructeurs d’exposer les caractéris-tiques avancées d’une architecture donnée ; c’est pourquoi il est parfois possible d’atteindre de meilleures performances sur les GPU Nvidia en utilisant CUDA plutôt qu’OpenCL [76]. Ensuite, dans la philosophie d’OpenCL, un kernel peut être exécuté sur des devices ayant des architectures matérielles différentes mais la portabilité des performances n’est pas ga-rantie. Au final le développeur devra spécialiser le code d’un kernel pour une architecture donnée s’il souhaite obtenir d’excellentes performances avec ce dernier.
Hybrid Multicore Parallel Programming (HMPP)
La solution HMPP [71, 40] propose une approche pragmatique qui repose sur l’annotation de code source existant en C, C++ et Fortran via des directives de compilation comme le proposait déjà OpenMP (voir section 3.1.3). Mais, à la différence d’OpenMP qui ne cible que les CPU, HMPP est capable d’exploiter les accélérateurs. En effet la solution HMPP comprend un compilateur source-to-source capable de générer du code CUDA ou OpenCL à partir des informations fournies par les directives de compilation (figure 3.4).

Le rapport de stage ou le pfe est un document d’analyse, de synthèse et d’évaluation de votre apprentissage, c’est pour cela chatpfe.com propose le téléchargement des modèles complet de projet de fin d’étude, rapport de stage, mémoire, pfe, thèse, pour connaître la méthodologie à avoir et savoir comment construire les parties d’un projet de fin d’étude.

Table des matières

1 Introduction 
I Contexte 
2 Simulation numérique et calcul haute-performance 
2.1 Univers de la simulation numérique
2.1.1 De notre perception de la réalité à la machine
2.1.2 Programme Simulation
2.1.3 Limites du modèle actuel
2.2 Architectures des supercalculateurs
2.2.1 Classification des architectures
2.2.2 Évolution des architectures
2.2.3 Bilan
3 Développement d’applications de calcul scientifique 
3.1 Langages et outils
3.1.1 Fortran : l’origine
3.1.2 Passage de messages
3.1.3 Mémoire partagée
3.1.4 High Performance Fortran (HPF)
3.1.5 Partitioned Global Address Space (PGAS)
3.1.6 Initiative HPCS du DARPA
3.1.7 Support d’exécution
3.1.8 Assemblage de composants parallèles
3.1.9 Parallélisme quasi-synchrone
3.1.10 Accélérateurs matériels
3.1.11 Langages dédiés
3.1.12 Frameworks de développement
3.1.13 Basé sur les modèles
3.1.14 Discussion
3.2 Génie logiciel et calcul scientifique
3.2.1 Conception guidée d’applications parallèles
3.2.2 Cycle de développement
3.3 Conclusion
II Contribution 
4 MDE4HPC : une approche modèle pour la simulation numérique 
4.1 Fondements théoriques
4.1.1 Principes généraux de l’IDM
4.1.2 L’approche Model Driven Architecture de l’OMG
4.2 Définition de l’approche MDE4HPC
4.2.1 Analyse de la situation
4.2.2 Proposition d’architecture
4.2.3 Processus de développement
4.3 Conclusion
5 Langage HPCML 
5.1 Syntaxe abstraite
5.1.1 Présentation générale
5.1.2 Paquetage kernel
5.1.3 Paquetage structure
5.1.4 Paquetage behavior
5.1.5 Paquetage output
5.1.6 Paquetage validation
5.1.7 Paquetage parametric
5.2 Syntaxe concrète
5.2.1 Démarche de conception suivie
5.2.2 Syntaxe concrète d’un diagramme comportemental
5.2.3 Syntaxe concrète de la partie structurelle
5.3 Conclusion
III Outillage et évaluation 
6 ArchiMDE : un outil pour l’approche MDE4HPC 
6.1 Un atelier de génie logiciel basé sur la plateforme Eclipse
6.2 Paprika Studio
6.2.1 Editeur généré
6.2.2 Editeur générique
6.2.3 Comparaison des approches
6.3 Fonctionnement de l’outil
6.4 Gestion de l’algorithmique de bas niveau
6.4.1 Génération directe
6.4.2 Génération incrémentale
6.4.3 Algorithmique modèle
6.4.4 Synchronisation
6.4.5 Bilan sur le choix du mode de gestion
6.5 Conclusion
7 Étude de cas : code d’électromagnétisme 3D 
7.1 Présentation du problème simulé
7.2 Modélisation de l’application avec HPCML
7.2.1 Processus de modélisation
7.2.2 Aperçu général
7.2.3 Calcul de la matrice des contributions
7.3 Conclusion
8 Atteinte des critères d’évaluation 
8.1 Portabilité
8.1.1 Cas d’un nouveau code de simulation
8.1.2 Cas d’un changement de machine
8.1.3 Remarques générales sur la portabilité
8.2 Abstraction et accessibilité
8.3 Séparation des préoccupations
8.4 Validation
8.5 Communauté et outillage
8.6 Évaluation globale
IV Perspectives et conclusion 
9 Vers une approche globale basée sur la modélisation 
9.1 Perspectives pour le langage HPCMLp
9.2 Perspectives pour le langage HPCMLn
9.2.1 Ajout de stratégies parallèles
9.2.2 Algorithmique de bas niveau
9.3 Perspectives pour le langage HPCMLe
9.3.1 Injection d’optimisations
9.3.2 Vers des codes multi-versionnés
9.3.3 Prise en charge du débogage
9.3.4 Models@run.time
9.4 Discussion
10 Conclusion 
A Méthodologie d’évaluation des solutions logicielles dédiées à la simulation numérique
Table des Figures
Acronymes
Bibliographie personnelle 

Télécharger le rapport complet

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *