• Nenhum resultado encontrado

4.4 Support des données partitionnées et repartitionnement

4.4.1 Interfaces des greffons

Greffons de données partitionnées

Les greffons de données partitionnées visent à diviser (virtuellement) un buffer de données en un ensemble de fragments. Un fragment est une instance d’un type de données POD2 opaque défini par le greffon.

Les greffons de données partitionnées doivent disposer d’au moins trois ports, illustrés sur la figure 4.4 : un port provide partition visant à contrôler le parti- tionnement d’un buffer de données, un port use part permettant de récupérer des informations nécessaires au partitionnement et au départitionnement d’un buffer de données ainsi que des ports provide fragMap et fragRepart dont l’objectif est de mettre à disposition les fragments du buffer de données partitionnées dans le but de soumettre des tâches opérant sur les fragments ou encore d’effectuer une opération de repartitionnement entre des données partitionnées. Détaillons le contenu de ces trois interfaces.

Port de contrôle du partitionnement La figure 4.11 décrit le type de l’interface partition. La méthode prepare prépare le partitionnement du buffer de données géré par le composant. Cette méthode sert en pratique à initialiser ou allouer des données nécessaires au partitionnement ou encore à récupérer toutes les informa- tions requises au partitionnement lui-même, notamment par le biais du port part.

La méthode partition déclenche une opération de partitionnement. Le buffer de données partitionné est celui qui est accessible par le port part. Le partitionne- ment d’un buffer de données engendre des fragments de données (accessibles par le port fragInfo. Lorsque le paramètre carryDepencencies est vrai, la méthode partition génère des dépendances entre le buffer de données global et chacun des

2. Les typesPlain Old Data (POD) sont spécifiés par la norme C++. Ces types n’utilisent pas de fonctionnalités orientées objet (p. ex. constructeurs, destructeurs, membres virtuels).

4.4. SUPPORT DES DONNÉES PARTITIONNÉES ET

REPARTITIONNEMENT 87

interface ExtFragMapPort<Fragment, FragmentId>

{

size_t fragmentCount();

Fragment getFragment(size_t fragId);

void* getDependency(size_t fragId);

}

Figure4.12 – Type de port fragMap minimaliste nécessaire au greffon définissant la relation d’identité.

fragments. Dans le cas contraire, aucune dépendance n’est produite. Plus de détails sont fournis en section 4.4.2. La méthode unpartition déclenche une opération de départitionnement. Après cette opération, les fragments ne sont plus accessibles. La méthodeclean libère les données éventuellement allouées par la méthodeprepare.

Port d’accès aux fragments Le type de l’interface fragMap n’est pas déterminé par Halley, mais par les greffons décrivant des langages de relations. En effet, ces greffons exploitent l’interfacefragMapdans le but de produire des tâches respectant une expression décrite dans les métatâches. Afin d’avoir une idée de l’utilité de ce port, un exemple de type d’interface minimaliste nécessaire au greffon de relations identity(définissant la relation d’identité) est présenté sur la figure 4.12. Plus gé- néralement, ce type peut dépendre d’un type de fragment défini par le greffon de données partitionnées et d’un type définissant un identifiant de fragment (permet- tant de retrouver un fragment dans la partition). Dans le cas de la relation identité, ce dernier n’est pas nécessaire. Une explication plus détaillée est fournie dans la sec- tion 4.5. La méthode fragmentCount fournit le nombre de fragments produits par l’opération de partitionnement. La méthode getFragment permet de récupérer un fragment à partir du numéro du fragment. Il est important de noter que la relation identité suppose que l’ensemble des fragments est ordonné selon des critères décrits par chaque greffon de données partitionnées. La méthodegetDependencypermet de récupérer un pointeur opaque à partir du numéro du fragment. Ce pointeur permet de définir des dépendances entre des fragments et des tâches ou même entre des fragments afin de pouvoir réaliser des opérations de repartitionnement.

Port de repartitionnement Tout comme le port fragMap, le type de l’interface fragRepart n’est pas contraint par Halley, mais par les greffons de partitionne- ment et de repartitionnement. En effet, l’interface fragRepart fournir l’ensemble des informations nécessaires aux greffons de repartitionnement afin qu’ils puissent effectuer des opérations de repartitionnement. Les experts de ces deux sortes de greffons doivent donc s’accorder sur la définition d’une interface adaptée. Halley propose une base d’interface minimaliste utile pour concevoir une interface dédiée en l’absence d’un accord précédemment établi. Cette interface est décrite par la figure 4.13. Les méthodes fragmentCount, getFragment et getDependency sont

interface ExtFragRepartPort<Fragment, FragmentId, MetaInformations>

{

size_t fragmentCount();

Fragment getFragment(FragmentId fragId);

void* getDependency(FragmentId fragId);

MetaInformations infos();

}

Figure 4.13 – Type de port fragRepart minimaliste nécessaire au greffon définis- sant la relation d’identité.

identiques à l’exemple d’interface fragMap excepté qu’elles opèrent sur des identi- fiants de fragments. L’interface proposée ajoute une méthode infos permettant de récupérer des attributs du greffon de données partitionnées (p. ex. taille du buffer, caractéristiques générales des fragments, etc.).

Spécification des interfaces La figure 4.14 montre un exemple de structures de données visant à définir un buffer de données de typeArray2Dpartitionné en blocs.

Ces structures de données sont exposées par le greffon de données et permettent aussi de déduire le type des ports du greffon.

Greffons de repartitionnement

Les greffons de repartitionnement doivent disposer d’au moins trois ports, illus- trés sur la figure 4.4: un portprovide repartitionvisant à contrôler le repartition- nement d’un buffer de données partitionnées et deux ports use srcPartet dstPart permettant de récupérer des informations des partitionnements source et destination pour effectuer des opérations de repartitionnement.

La figure4.15 décrit le type de l’interface repartition. Les méthodes prepare etcleansont identiques à celles de l’interface4.11. La méthoderepartitiona pour effet de réaliser une opération de repartitionnement. Une telle opération vise à définir des dépendances entre les fragments issus du partitionnement référencé par le port srcPart et ceux qui sont issus du partitionnement référencé par le port dstPart.

Le fonctionnement des opérations de partitionnement et de repartitionnement est décrit dans la section 4.4.2.

Le type des ports srcPart et dstPart est identique aux ports fragMap des greffons de données partitionnées. Néanmoins, le type du port srcPart peut être différent du type de dstPart étant donné qu’un greffon peut effectuer un repar- titionnement entre des types de données partitionnées différents (les deux doivent cependant appartenir au même type de buffer de données).

4.4. SUPPORT DES DONNÉES PARTITIONNÉES ET

REPARTITIONNEMENT 89

namespace BlockedArray2D {

struct Fragment {

void* ptr; // pointer to the top left origin of the block size_t width, height; // size of the block

size_t ld; // leading dimension (offset between two lines) }

struct FragmentId {

size_t x, y; // position of the block in the block grid }

struct MetaInformations {

size_t blockWidth, blockHeight;

} }

Figure4.14 – Structures de données permettant de définir un buffer de données de typeArray2D partitionné en blocs.

interface ExtRepartitionPort {

void prepare();

void repartition();

void clean();

};

Figure 4.15 – Type de port repartition permettant de contrôler les greffons repartitionnement.