• Aucun résultat trouvé

7.3 Skeleton algorithmique de la propagation SIMD en 4-voisinage

7.3.5 Calcul des nivellements

Outre la fonction distance, le style de travail que nous avons décrit par les skeletons algorithmiques de la propagation peut être utilisé également pour définir les algorithmes évaluant des nivellementsMey03,

cela non seulement pour les nivellements plats, cf. fig. 7.7(a), mais également pour les lambda-nivellements, cf. fig. 7.7(b). Ainsi présentés, nous pouvons percevoir les nivellements plats en tant que cas spécial des lambda-nivellements pour la valeur λ = 0.

Notons également que la technique de propagation des valeurs lors du travail avec les nivellements est très semblable à celle que nous utilisons lors du travail avec la fonction distance, même si les nivellement constituent une opération plus complexe que la fonction distance.

En revanche, ils diffèrent de la fonction distance par leur caractère géodésique et par la propagation des valeurs jusqu’à l’idempotence. Par la suite, nous n’allons présenter que les définitions des algo- rithmes pour une seule itération, l’application répétitive de ces algorithmes peut être facilement dérivée suivant les même règles que celles présentées pour les opérations géodésiques non-dépendantes du sens de parcours, cf. la section 5.3, page 115.

f - fonction de référence

m - marqueur

Λ0

m- nivellements (plats)

(a)Nivellements plats

f - fonction de référence m - marqueur Λλ m- nivellements (lambda) (b) λ-nivellements FIG. 7.7 : Nivellements

7.3.5.2 Nivellements en tant que combinaison des nivellements partiels

L’implémentation des nivellements que nous allons présenter va utiliser les skeletons que nous avons décrits précédemment et va s’appuyer sur deux nivellements partiels que nous appelons les sur- nivellements et les sous-nivellements et qui sont illustrés sur la fig. 7.8. Ces deux opérations ont, en effet, la structure de fonctionnement de la propagation identique, ce qui les différencie est l’opération du kernel d’exécution.

Ces fonctions ont des propriétés très intéressantes. Étant donné la fonction de référence f et le mar- queur m, les lambda-sous-nivellements Λλ−

m (f ) de la fonction f contraintes par le marqueur m sont

identiques aux nivellements Λλ

m(f ) dans le domaine de l’image où m > f , dans le reste du domaine

ils sont identiques à la fonction f. Par dualité, les lambda-sur-nivellements Λλ+

m (f ) de la fonction f

contraintes par le marqueur m sont identiques aux nivellements Λλ

m(f ) dans le domaine de l’image où

m < f , dans le reste du domaine ils sont identiques à la fonction f . Afin d’obtenir les lambda-nivelements Λλ

m(f ) à partir de ces sur- et sous-nivellements, nous allons

combiner ces deux derniers selon la formule suivante :

Λλm(f ) =n

Λλ−m (f ) m > f

f m = f

Λλ+m (f ) m < f

(7.1)

L’équation 7.1 est la définition mathématique théorique. Dans la pratique nous allons profiter des pro- priétés des nivellements pour diminuer le nombre d’opérations arithmétiques à effectuer. Tout d’abord, nous allons profiter de l’identité des nivellements avec la fonction de référence f pour m = f afin d’éli- miner une condition à vérifier. Les sur- et sous-nivellements sont bornés sur les sous-domaines et les expressions suivantes sont valides :

m ≥ Λλ−m (f ) ≥ f, ∀m ≥ f m ≤ Λλ−m (f ) ≤ f, ∀m ≤ f (7.2) et nous allons les utiliser pour éliminer la fonction f de la formule pour la combinaison des nivellements ce qui va se traduire par le travail avec une image en moins. Ainsi, nous pouvons décrire le même travail par la formule suivante :

Λλm(f ) =

n Λλ−m (f ) m ≥ Λλ−m (f )

Λλ+m (f ) m < Λλ−m (f ) (7.3)

C’est l’équation 7.3 que nous allons utiliser en pratique pour effectuer la combinaison des deux nivelle- ments partiels.

f - fonction de référence m - marqueur Λλ m- nivellements (lambda) f - fonction de référence m - marqueur Λλ- m– sous-nivellements (lambda) True False m > f f - fonction de référence m - marqueur Λλ+ m– sur-nivellements (lambda)

FIG. 7.8 : Calcul des nivellements en tant que combinaison des sur-nivellements et les sous-nivellements

7.3.5.3 Algorithmes pour une itération des nivellements partiels

Le skeleton de la propagation SIMD que nous avons défini dans la section 7.3.3 va nous servir de charpente pour la construction des algorithmes qui vont implémenter les sur-nivellements et les sous- nivellements. Tout d’abord, clarifions les images que nous attendons à l’entrée de nos algorithmes et quelle sera leur fonction lors de la propagation.

La fonction de référence f (cf. fig. 7.8) va passer dans les fonctions de propagation en tant que masque et les valeurs du marqueur m des nivellements (cf. fig. 7.8) seront utilisées en tant que valeurs initiales à partir desquelles nous commencerons la propagation et qui vont devenir, après avoir appliqué les quatre phases de propagation SIMD, les valeurs résultantes d’une itération des nivellements partiels. La figure 7.9 illustre cette situation.

L’array d’entrée ar des fonction définissant les nivellements partiels va être composé de la même manière que celui utilisé par la fonction distance – par des tuples (masque, valeur) et le type de cet array sera, par conséquent, Ar (I, I) (α, α).

(a) Image du masque "*msk" pour la propagation correspondant à la fonction f de

référence des nivellements

(b)Image des valeurs à propager "*val" correspondant à la fonction m du marquer des

nivellements

FIG. 7.9 : Les images d’entrée aux fonctions de sur- et sous-nivellements et l’exemple de leur contenu.

Une itération de lambda-sous-nivellements est définie par la fonction lolevelSQR4 :

lolevelSQR4 :: [ Char] → I → I → Ar ( I , I ) (α,α) → Ar ( I , I ) (α,α) lolevelSQR4 axe pvecsz lmb ar = propAlgSQR4 axe pvecsz

( λ (vmsk,vval) (emsk,eval) → maxSIMD emsk (minSIMD (vval+lmb) eval) )

ar

où le terme λ définit le kernel de la propagation directionnelle et le paramètre lmb définit la pente des lambda-sous-nivellements. En spécifiant sa valeur à 0, nous obtenons les sous-nivellements plats. La signification des autres paramètres de cette fonction est identique à celle des paramètres pour la fonction distance (cf. 7.3.4) : axe définit l’axe de stockage des données dans la mémoire, pvecsz est le nombre des éléments que nous pouvons traiter en même temps par les instructions SIMD de notre architecture multimédia et ar est l’array d’entrée composé des tuples (masque, valeur).

Par analogie, nous définissons une itération des lambda-sur-nivellements par la fonction hilevelSQR4 :

hilevelSQR4 :: [ Char] → I → I → Ar ( I , I ) (α,α)→ Ar ( I , I ) (α,α) hilevelSQR4 axe pvecsz lmb ar = propAlgSQR4 axe pvecsz

( λ (vmsk,vval) (emsk,eval) → minSIMD emsk (maxSIMD (vval−lmb) eval) )

ar

où le seul changement par rapport à la fonction des lambda-sous-nivellements est dans la définition du terme λ définissant le kernel de la propagation directionnelle.

7.3.5.4 Algorithme pour une itération des nivellements

Comme nous l’avons déjà expliqué dans la section 7.3.5.2, une itération des nivellements (finaux) sera obtenue par la combinaison des résultats d’une itération des sur- et sous-nivellements (partiels) selon l’équation 7.3.

La fonction levelSQR4 définit cette composition :

levelSQR4 :: [ Char] → I → I → Ar ( I , I ) (α,α)→ Ar ( I , I ) (α,α)

levelSQR4 axe pvecsz lmb ar =

(mkAr2DFromAr2DPVec axe)

◦ listArray (bounds $ lo )

map2 ( λ (lomsk,loval) (himsk,hival) → cndmoveSIMD (testSIMD lomsk ( ≥ ) loval ) loval hival ) (elems◦ (mkAr2DPVec axe pvecsz)$lo )

(elems◦ (mkAr2DPVec axe pvecsz)$hi )

where

lo = (lolevelSQR4 axe pvecsz lmb)$ar hi = (hilevelSQR4 axe pvecsz lmb)$ar

Nous y évaluons d’abord les résultats lo et hi de nivellements partiels en utilisant la fonction lolevelSQR4 des sous-nivellements et la fonction hilevelSQR4 des sur-nivellements. L’expression λ définit sur place la fonction de composition SIMD des nivellements en utilisant la fonction testSIMD (cf. sa définition, page 202) qui crée un vecteur paqueté du masque que l’on utilise aussitôt dans la fonction de dépla- cement conditionnel cndmoveSIMD (cf. sa définition, page 203). Cette construction est une technique courante pour exprimer l’expression conditionnelle if then else pour les données SIMD.

La fonction map2 applique la fonction λ sur les éléments de deux streams. Les fonctions mkAr2DPVec et mkAr2DFromAr2DPVec sont utilisées pour vectoriser et dé-vectoriser les arrays, respectivement, et les fonction elems et listArray sont les fonctions standards du Haskell pour le passage d’un array à un stream et vice versa, respectivement.