• Nenhum resultado encontrado

Cette section s’intéresse aux greffons permettant de décrire des langages de rela- tions et à la transformation des métatâches en composants glus. Contrairement aux autres greffons, ceux qui définissent les relations sont des extensions du compilateur de Halley. Ils sont partiellement responsables de la génération des composants glus issus des métatâches. Leur mise en œuvre s’adresse donc à des personnes ex-

4.5. LANGAGES DE RELATIONS 93 périmentées ayant une bonne compréhension de l’architecture du compilateur ainsi que des connaissances poussées du fonctionnement des supports exécutifs (usage d’OpenMP). Cependant, à terme, il est envisageable de relayer la définition des greffons de relations à des composants externes au compilateur, tout comme les greffons de partitionnement par exemple.

L’objectif de cette section est de montrer comment les greffons de relations fonc- tionnent et comment ils s’intègrent dans le processus de compilation d’Halleyafin de générer des composants glus issus des métatâches (indépendamment des détails de mise en œuvre).

4.5.1 Fonctionnement général et intégration

Halley ne fixe que peu de contraintes sur les greffons de relations qui peuvent être de nature très diverse. Pour bien comprendre le fonctionnement des greffons de relations et leurs liens avec d’autres sortes de greffons, cette section analyse un exemple de prototype de greffonaligndécrivant desstencils (c.-à-d. traitement ap- pliquant un calcul dépendant du voisinage pour chaque point d’un maillage) simples.

Un greffon de relations a pour objectif principal de définir un langage de relations.

C’est-à-dire qu’il spécifie la syntaxe et la sémantique d’un langage dont le rôle est de décrire comment regrouper des fragments issus de buffers de données partitionnées ensemble afin de soumettre des tâches qui opèrent sur ces fragments. Ces greffons sont majoritairement responsables de la génération des composants glus issus des métatâches lors de la compilation.

Un greffon de relations est constitué d’une spécification en deux parties et d’une mise en œuvre. Une première partie de la spécification, dédiée aux concepteurs d’applications, comporte : un langage de relations lié à un identifiant et un type d’interface pour les portscomputedes métatâches utilisant ce langage. Une seconde partie de la spécification, dédiée aux experts définissant les greffons de données partitionnées, contient un type d’interface pour les portsfragMap. La mise en œuvre est constituée conjointement d’une classe C++ et d’un fichier de template intégrés au compilateur.

Étant donné que le fonctionnement des greffons dépend des types de métatâche traités, cette section utilisera l’exemple de métatâche décrit par la figure4.18comme fils conducteur. Cette métatâche permet d’effectuer un stencil cinq points. Elle dispose d’un port d’entrée in et d’un port de sortie out, tous les deux de type BlockedArray2D et configurés pour traiter des buffers de tailles carrés (paramétrés par dSize) avec des blocs de tailles carrés (paramétrés par bSize). Le contenu de la configuration de la métatâche est un code Python, exécuté à la compilation lors de la phase d’analyse sémantique, définissant les valeurs des attributs des greffons de données (partitionnées ou non) associés à chaque port à partir des attributs de métatâche (accessible par la variablemt). Les attributs XMLdataPartitionSetter etdataBufferSetter font référence à des fonctions de la configuration.

<metatask id="StencilMt">

<parameter id="dSize" type="uint64"/>

<parameter id="bSize" type="uint64"/>

<inPort id="in" type="BlockedArray2D" dataBufferSetter="fData"

dataPartitionSetter="fPart"/>

<outPort id="out" type="BlockedArray2D" dataBufferSetter="fData"

dataPartitionSetter="fPart"/>

<relation language="align">

out(x,y) = in(x-1,y), in(x,y), in(x+1,y), in(x,y-1), in(x,y+1)

</relation>

<setting language="python3">

def fData(mt):

return dict(width=mt.dSize, height=mt.dSize, elemSize=8) def fPart(mt):

return dict(blockWidth=mt.bSize, blockHeight=mt.bSize)

</setting>

</metatask>

Figure4.18 – Exemple de type de métatâche utilisant le langage de relationsalign.

4.5.2 Langages de relations

La figure 4.19 présente la grammaire du langage de relationsalign. Ce langage permet de décrire à gauche de l’expression des fragments dans lesquels les tâches écrivent et à droite les fragments lus (ou des deux côtés pour les fragments en lecture-écriture). Chaque occurrence de fragId fait référence à un nom de port de la métatâche (plus précisément il fait référence aux buffers de données partitionnées transmis par le port). Toutes les occurrences de dimAccess doivent posséder des dimId consécutifs identiques (c.-à-d. pas de transposition possible). Les opérations arithmétiques des membres de droite permettent d’accéder aux fragments voisins (c.-à-d. nombre de fragments). Les buffers de données référencés par les membres de gauche doivent posséder des caractéristiques identiques (c.-à-d. dimension, taille, partitionnement).

La métatâche décrite par la figure4.18contient un exemple d’expression acceptée par langage de relations align. Dans cet exemple, pour chaque fragment du port outindexé par px, yq, on soumet une tâche disposant de cinq fragments, décrits par la partie droite de l’expression, appartenant tous au même port in. Les positions des fragments à droite de l’expression sont relatives aux fragments à gauche de l’expression.

4.5.3 Interfaces

Pour fonctionner, un composant glu issu d’une métatâche doit posséder au moins trois ports : un portgo possédant une seule méthodego (sans paramètres) permet- tant de soumettre des tâches (dont le greffon de relations est responsable), un port

4.5. LANGAGES DE RELATIONS 95

integer = ? regular expression: [0-9]+ ?;

fragId = ? regular expression: [a-zA-Z_][a-zA-Z0-9_]+ ?;

dimId = ? regular expression: [xyzwvu] ?;

dimAccess = dimId, [("+"|"-"), integer)];

lterm = fragId, "(", dimId, {",", dimId} ")";

rterm = fragId, "(", dimAccess, {",", dimAccess} ")";

lterms = lterm, {",", lterm};

rterms = rterm, {",", rterm};

expr = lterms, "=", rterms;

Figure 4.19 – Grammaire EBNF (ISO/IEC 14977 1996) du langage de relations align. Les virgules désignent une séquence de parties concaténées. Les crochets dénotent des parties optionnelles. Les accolades indiquent des parties répétables plusieurs fois. Les parenthèses sont des parties prioritaires. Les barres verticales marquent un choix à effectuer parmi plusieurs parties. Les parties entre des points d’interrogation sont des commentaires décrivant une partie de la grammaire.

compute visible par les utilisateurs et un port fragMap visible par les experts. Les types de ces deux derniers ports doivent être spécifiés par un greffon de relations.

Port de calcul L’exécution de chaque tâche soumise par le port go exécute une méthode compute de l’interface compute. Cette méthode prend en paramètre l’en- semble des fragments associés à la tâche.

La liste des fragments à fournir et la manière de les transmettre à la méthode compute est grandement dépendant du greffon de relations considéré ainsi que de la métatâche. En effet, certains greffons peuvent fournir par exemple un nombre fixe de fragments par tâche alors que d’autre non. Similairement, dans de nombreux cas, chaque fragment est associé à un rôle et doit donc être différentiable des autres.

Dans le cas d’un stencil par exemple, la mise en œuvre de la méthode compute doit pouvoir différencier les fragments, car des traitements différents peuvent être appliqués sur les fragments en fonction de leur position relative. De plus, il est aussi nécessaire dans le cas des stencils de pouvoir effectuer des traitements particuliers aux conditions limites (fragments aux “bords” des maillages). Enfin, les paramètres fournis, par le biais de cette interface, doivent être des structures de type POD de taille raisonnable (une grande taille peut avoir un effet néfaste sur les perfor- mances). Pour toutes ces raisons, Halley ne propose pas d’interface généraliste et laisse chaque greffon spécifier un type générique (paramétré par le type de mé- tatâche) d’interface spécialisée.Halley spécifie seulement que l’interface compute détient une unique méthodecomputedisposant d’un unique paramètre, dont le type, nommée Fragments, est généré par le greffon de relations à partir du type de méta- tâche.

La figure4.20 montre le type d’interface généré par le greffon de relationsalign à partir du type de la métatâche StencilMt de la figure 4.18. Chaque élément de la structure pointe sur un fragment, ou vaut une valeur nulle lorsque le fragment

struct Fragments {

BlockedArray2D::Fragment* f0_out;

BlockedArray2D::Fragment* f1_in, f2_in, f3_in, f4_in, f5_in;

}

interface StentilMt_ComputePort {

void compute(Fragments fragment);

}

Figure4.20 – Type du portcomputedu composant glu généré depuis la métatâche StencilMt par le greffon de relations align.

interface ExtFragMapPort<Fragment, FragmentId>

{

size_t fragmentCount(size_t dimensionId);

Fragment getFragment(FragmentId fragId);

void* getDependency(FragmentId fragId);

bool isValid(FragmentId fragId);

}

Figure 4.21 – Type de port fragMapdéfini par le greffon de relations align.

est en dehors des limites des buffers de données (espace non torique). L’ordre des éléments dans la structure correspond à l’ordre des fragments dans l’expression.

Port d’accès aux fragments Afin de pouvoir énumérer les fragments, ou même d’analyser certaines de leurs propriétés (p. ex. localisation sur les “bords” du maillage dans le cas des stencils), les composants glus générés par les greffons de relations possèdent une interface fragMapvisant à interagir avec les greffons de partitionne- ment. Le type de cette interface est intrinsèquement lié à la nature de la relation. Il est donc indépendant du type de métatâche traité. Chaque type d’interface fragMap peut être supporté par une classe de greffon de données partitionnées (p. ex. buffers de données multidimensionnels partitionnés en blocs réguliers).

La figure 4.12, présentée en section 4.4.1, fournit le type d’interface fragMap défini par le greffon de relations identity.

La figure 4.21 montre le type d’interface fragMap défini par le greffon de rela- tionsalign. Cette interface a connaissance de la topologie de l’espace des fragments contrairement à celle issue de la relation d’identité. Elle a aussi connaissance de la dimension de l’espace des fragments (connu à la compilation à partir de l’expres- sion de relation et des ports du type de métatâche traité) et du contenu du type FragmentId. Pour savoir si un fragment est en dehors des bornes d’un buffer, le