Projet : LANDE

previous up next contents
Précédent : Actions «aval» Remonter : Résultats nouveaux Suivant : Contrats industriels (nationaux, européens et


Sous-sections


   
Actions «amont»

Nous décrivons dans cette partie les travaux à plus long terme sur les langages fonctionnels (module 6.2.1), la programmation par aspects (module 6.2.2), et les architectures de logiciels (module 6.2.3).

   
Implantation des langages fonctionnels

Taxonomie des implantations séquentielles



Participant : Pascal Fradet.

Mots clés : Compilation, Langage fonctionnel, Transformation de programme .

Résumé :

De nombreuses techniques ont été proposées pour implanter les langages fonctionnels et il est difficile d'établir des comparaisons rigoureuses entre les différentes options existantes. Nous avons proposé un cadre formel pour décrire et comparer les techniques de compilation des langages fonctionnels. Cela nous a permis d'établir une taxonomie des mises en oeuvre de langages fonctionnels, d'étudier l'expression d'optimisations standards et la conception de machines hybrides (i.e. intégrant plusieurs choix de compilation).

De nombreuses techniques ont été proposées pour implanter les langages fonctionnels et il est difficile d'établir des comparaisons rigoureuses entre les différentes options existantes. Afin d'apporter des éléments de solution à ce problème difficile, nous avons proposé un cadre formel pour décrire et comparer les techniques de compilation des langages fonctionnels [[14]]. Nous avons repris l'idée centrale de nos précédents travaux [[6]] qui consiste à définir le processus de compilation comme une suite de transformations de programmes dans le cadre fonctionnel. Nous avons couvert une grande partie du domaine en considérant les mises en oeuvre de l'appel par valeur et l'appel par nécessité, qu'elles soient basées sur les environnements ou la réduction de graphe. Nous avons identifié pour chaque étape de compilation plusieurs choix fondamentaux et nous les avons décrits comme des transformations de programmes. La description dans un cadre unique a permis d'établir une taxinomie des mises en oeuvre de langages fonctionnels. Nous avons classifié de nombreuses implantations classiques comme la SECD, la Cam, la G-machine, Tim, etc. Nous avons également étudié l'expression d'optimisations classiques, la conception de machines hybrides (i.e. intégrant plusieurs choix de compilation) et proposé des comparaisons formelles sous la forme d'étude de complexité des transformations [[14]]. Ce travail a été réalisé en collaboration avec Rémi Douence, actuellement à l'École des Mines de Nantes.

Langages restreints pour machines parallèles



Participants : Pascal Fradet, Julien Mallet.

Mots clés : Langages dédiés, Schémas de programme, Compilation, Analyse de coût, Parallélisme .

Résumé :

Nous avons proposé un langage spécialisé pour machines parallèles. Les restrictions du langage source permettent de choisir automatiquement la meilleure distribution de données parmi un ensemble de distributions standards. Ce choix repose sur une analyse de coût exacte et symbolique prenant en compte les temps de calcul et les temps de communication.

Il n'existe pas de langage idéal pour programmer les machines parallèles : on trouve d'une part des langages à parallélisme explicite efficaces mais non portables et très complexes à utiliser; et d'autre part des langages simples et portables mais dont la compilation est complexe et relativement inefficace. La démarche que nous avons adoptée est celle d'un langage spécialisé permettant une estimation exacte du coût de l'implantation parallèle ([[27]],[[33]]). Le résultat de cette analyse de coût, qui prend en compte les temps de calcul et les temps de communication, conditionne des choix de compilation comme la distribution de données, l'ordonnancement, et certaines optimisations.

Notre langage source est un langage fonctionnel du premier ordre où la récursivité générale et les conditionnelles sont remplacées par des collections de schémas de programmes (patrons) [[11]]. Ces restrictions permettent de choisir automatiquement la meilleure distribution de données parmi un ensemble de distributions standards. Ce choix repose sur une analyse de coût exacte et symbolique (les tailles effectives des données n'ont pas à être connues).

Ce travail est un exemple de fertilisation croisée entre trois domaines différents : la parallélisation automatique de Fortran, les langages fonctionnels et les langages à patrons. Les paralléliseurs Fortran ont introduit des analyses exactes de temps d'exécution symbolique pour des sous-ensembles du langage. Nous avons étendu ces travaux pour définir notre analyse de coût et nous avons explicité les restrictions nécessaires pour assurer l'exactitude de l'analyse. Nous avons également adapté des résultats obtenus dans le cadre des langages fonctionnels pour manipuler les tableaux de façon efficace. Les langages à patrons fournissent un cadre pour définir les restrictions du langage source en introduisant des schémas de calculs parallèles. Nous avons étendu cette approche en introduisant des patrons de communication (dénotant les routines optimisées des machines parallèles) et des patrons de masque (qui permettent d'évaluer exactement la répartition des calculs sur les processeurs). Les résultats préliminaires sont prometteurs puisque, sur les quelques exemples traités, nos programmes se sont révélés avoir les mêmes performances que les programmes HPF équivalents (avec des distributions manuelles). L'analyse de coût calcule des temps d'exécution très proches de la réalité et les distributions sélectionnées automatiquement se sont révélées être les meilleures en pratique.

Programmation par aspects



Participant : Pascal Fradet.

Mots clés : Aspects, Cadre générique, Programmation robuste, Exceptions .

 

Résumé :

La programmation par aspects propose de décrire un logiciel comme un ensemble formé d'un composant principal et d'une collection d'aspects. Un outil, appelé tisseur, est chargé de produire automatiquement un programme intégrant les différents aspects au composant principal. Nous avons commencé à nous intéresser à cette approche en proposant à la fois un cadre générique de programmation par aspects et son application à la production de logiciels robustes.

La programmation par aspects est un paradigme de programmation proposé tout récemment par une équipe du PARC (Xerox). Dans cette approche, un logiciel est formé d'un composant principal et d'une collection d'aspects décrivant des tâches comme la gestion mémoire, la synchronisation, les optimisations, etc. Un outil, appelé tisseur, est chargé de produire automatiquement un programme intégrant les différents aspects au composant principal. L'intérêt de cette approche est de localiser (dans les aspects) des choix de mise en oeuvre qui seraient sinon dispersés dans le code source. Nous avons commencé à nous intéresser à cette approche en proposant à la fois un cadre générique de programmation par aspects et son application à un exemple concret [[22]].

Dans notre cadre, un aspect est une collection de transformations syntaxiques de programmes. Le tisseur effectue un calcul de point fixe appliquant ces transformations autant que faire se peut sur le composant principal. Ce cadre permet également d'associer des analyses de programmes au tisseur afin que les aspects puissent reposer sur des critères sémantiques aussi bien que syntaxiques.

Nous nous intéressons à l'utilisation de ce paradigme pour la production de logiciels robustes. Un programme robuste possède un domaine standard d'entrées sur lequel il termine (et satisfait ses spécifications) et un domaine exceptionnel sur lequel il termine en produisant une erreur ou une exception. L'écriture de programmes robustes implique le plus souvent de nombreux tests répartis dans le code (par exemple pour vérifier les débordements ou les accès aux tableaux). Il est difficile de prévoir et d'insérer tous les tests nécessaires. De plus, ces tests rendent le programme source difficile à lire et à maintenir. De fait, peu de programmes sont robustes. Dans le cadre de la programmation par aspects, un programme robuste peut être décomposé en un programme (par exemple codé en C ) qui respecte sa spécification pour le domaine standard mais pas forcément pour le domaine exceptionnel et un aspect décrivant le domaine exceptionnel. L'aspect prend la forme d'un ensemble de propriétés (e.g., 1 $ \leq$ X $ \leq$ 100 qui spécifie que la variable X doit être comprise entre 1 et 100 durant toute l'exécution). Le programme résultant du tissage est un programme robuste, équivalent au composant pour le domaine standard mais qui termine par un message d'erreur pour le domaine exceptionnel. Pour cette application, le tisseur se doit d'intégrer une analyse de programmes afin d'éviter l'insertion de tests superflus. Nous terminons actuellement la formalisation du cadre générique et la définition du langage d'aspects pour la programmation robuste. Ce travail est effectué en collaboration avec Mario Südholt de l'École des Mines de Nantes.

   
Les architectures de logiciels

Notre réflexion sur l'introduction d'un système de types pour le langage Gamma nous a conduit à proposer une notion de type graphe correspondant à une classe de graphes d'une même forme. Ces graphes sont manipulés par des réactions qui extraient un sous-graphe selon des conditions locales et le remplacent par un nouveau sous-graphe. Nous avons conçu un algorithme de vérification qui permet d'assurer que le type est préservé par une réaction. Ces types peuvent alors être vus comme des invariants sur la forme des données.

Nous avons proposé une nouvelle version de Gamma, appelée Gamma Structuré, qui intègre les types graphes [[16]]. Il s'est avéré que les types graphes peuvent apporter des solutions à des problèmes très différents. Nous avons notamment étudié leur application pour la description d'architectures de logiciels [[19]].

Gamma Structuré



Participants : Pascal Fradet, Daniel Le Métayer.

Mots clés : Réaction chimique, Multi-ensemble, Structure de données, Type graphe, Vérification de type, Invariant .

Résumé :

Nous avons proposé une version de Gamma qui intègre un moyen de définir des données structurées sans pour autant remettre en cause le modèle de calcul de base. Les types graphes permettent une description des structures de données de nature «topologique», sous forme de relations entre les valeurs du multi-ensemble. Ces types peuvent être vus comme des invariants sur les multi-ensembles, le point crucial étant que ces invariants peuvent être prouvés automatiquement. On obtient ainsi une vérification de types pour Gamma Structuré.

Le formalisme Gamma permet une description abstraite des programmes, dépourvue de contraintes d'ordonnancement inutiles.

Gamma Structuré intègre dans le langage un moyen de définir des données structurées sans pour autant remettre en cause le modèle de calcul de base. La difficulté vient du fait qu'on ne peut recourir à la méthode habituelle pour définir des structures de données (les types récursifs) car ceci induirait un style de programmation récursive (avec une manipulation globale des données) incompatible avec les principes de Gamma. Les types graphes permettent une description des structures de données de nature «topologique», sous forme de relations entre les valeurs du multi-ensemble [[16]]. Ces types peuvent être vus comme des invariants sur les multi-ensembles, le point crucial étant que ces invariants peuvent être prouvés automatiquement. On obtient ainsi une vérification de types pour Gamma Structuré.

Le bénéfice est double:

Architectures de logiciels



Participants : Pascal Fradet, Daniel Le Métayer, Michaël Périn, Siegfried Rouvrais.

 

Mots clés : Architecture de logiciel, Coordination, Communication, Style, Vue, Analyse, Vérification .

Résumé :

Nous avons proposé une manière de spécifier des architectures en terme de graphes. La description d'une application est séparée en deux niveaux bien identifiés: d'une part, l'ensemble de ses entités de base qui représentent des calculs autonomes; d'autre part la coordination de ces entités. Les entités individuelles peuvent être décrites dans des langages traditionnels (par exemple séquentiels) et la coordination est assurée par un composant défini séparément: le coordinateur.

Le domaine des architectures de logiciels a connu un développement important ces dernières années. La tendance actuelle consiste à proposer des langages spécifiques pour la définition de l'architecture (ou organisation globale) de gros logiciels et à fournir des outils pour manipuler ces architectures et en prouver des propriétés. Il s'avère en fait que les propriétés qu'on souhaite vérifier dans ce contexte sont de natures très diverses et que chacune d'elle peut demander une présentation différente de l'organisation du logiciel. La définition d'une architecture comme un ensemble de vues complémentaires s'impose donc mais il est alors nécessaire de traiter le délicat problème de la cohérence de ces vues multiples. Nous avons abordé cette question en proposant une notion de cohérence locale définie à l'aide de relations binaires et de contraintes structurelles sur des vues représentées par des graphes non interprétés [[26]]. Par rapport à la cohérence «d'implémentation» utilisée dans le cadre des langages de spécification, notre définition facilite le traitement de vues hétérogènes. Cet aspect est crucial dans le contexte des architectures de logiciels où les vues doivent pouvoir être exprimées naturellement dans des formalismes très différents.

Une des vues les plus étudiées dans le domaine des architectures de logiciels est celle qui concerne les communications et les synchronisations entre composants. Nous avons abordé cette question en proposant une manière de décrire les applications en séparant deux niveaux bien distincts: d'une part, l'ensemble de ses entités de base qui représentent des calculs autonomes; d'autre part la coordination de ces entités (création, destruction, établissement des liens de communication). Les entités individuelles peuvent être décrites dans des langages traditionnels (par exemple séquentiels) et la coordination est assurée par un composant défini séparément: le coordinateur. L'ensemble des entités et leurs liens de communication forment un graphe qui doit vérifier une forme particulière, qu'on appelle le style de l'architecture. Ce style est décrit par un type graphe et on peut vérifier que le coordinateur, exprimé en terme de récritures de graphes dans le style de Gamma Structuré, assure bien l'invariance de ce type. L'avantage de cette démarche est de concilier une vision dynamique de l'architecture avec des possibilités de vérification statique [[19]].

En collaboration avec le projet SOLIDOR, nous étudions également le raffinement d'architectures de logiciels vers des systèmes à agents mobiles. L'idée est de raisonner sur une vue de l'architecture faisant apparaître les volumes de données échangés afin de choisir la mise en oeuvre la plus adaptée (agent mobile ou RPC).

Nos travaux sur les architectures de logiciels s'appuient sur des études de cas (système de contrôle de trains proposé par la société néerlandaise Signaal, sécurité du système d'informations de l'Irisa). Ils se concrétiseront dans le cadre d'une action industrielle conduite en collaboration avec le projet EP-ATR et qui impliquera Matra Systèmes Informatiques AQL et TNI. Cette action, qui est commanditée par le Celar, porte sur la conception d'un outil d'aide à la mise au point d'architectures sécurisées.



previous up next contents
Précédent : Actions «aval» Remonter : Résultats nouveaux Suivant : Contrats industriels (nationaux, européens et