EQUIPOS ELÉCTRICOS
5 DISCUSIONES Y CONCLUSIONES
One of the design goals of the PCF is to allow pContainers with various parti- tions and mapping on the machine. This can be achieved by specifying the desired partitions and partition mapper as template arguments at compile time. The data redistribution is the process of reorganizing the data of a pContainer based on a new data distribution (new partition and/or partition mapping) as described in Chap- ter IV, Section C. We integrate into the PCF support for allowing an individual pContainer to change its partition and partition mapping dynamically during the execution. This is achieved by using polymorphic implementations for both the par- tition and partition mapper and providing the necessary support to move data across different locations. For example, for pArray we mentioned we currently support bal- anced, blocked and explicitly blocked partitions. These three types of partitions can be interchanged within the same pContainer instance dynamically. In this section we describe the support implemented in the PCF to allow this functionality.
The Partition Proxy is a polymorphic wrapper for real partitions and pro- vides the necessary support to change the underlying partition at runtime. There are some trade-offs when using a partition proxy. While giving users more flexibil- ity it involves virtual methods with the associated overhead and missed opportuni- ties for compile time optimizations. The default partitions of all pContainers are proxy partitions and the framework provides proxies for all components of the tax- onomy: partition proxy indexed, partition proxy dynamic, partition proxy sequence, partition proxy associative, and partition proxy relation. When a partition proxy is used, the interface of the pContainer is automatically extended with the the following interface:
1 void r e d i s t r i b u t e ( n e w p a r t i t i o n [ , p a r t i t i o n m a p p e r ] ) ; 2 void r e d i s t r i b u t e ( r e d i s t r i b u t i o n m a p ) ;
SD_0 SD_1 SD_0 S SD_1 Partition 1
Partition 2 S
Fig. 13. Redistribution for two given partitions. Section S (one or more elements) of sub-domain 1 in first partition will migrate to sub-domain 0 in the second partition.
Trying to invoke the above methods on a pContainer with a non proxy partition will generate a compiler error.
While performing the redistribution, there is the new partition and/or partition mapper and the original ones. A naive redistribution approach can simply create a new pContainer organized according to the new partition, copy data from the old storage and delete the old storage. However this is a very inefficient approach. To assist users in performing efficient redistribution, we introduce the redistribution map which contains only the elements that will migrate from a sub-domain to a new sub-domain. A common case occurs when the repartition moves elements across neighboring sub-domains. The redistribution map will benefit the redistribution in this situation. In Figure 13, we depict a case were the redistribution will have to migrate only the data corresponding to sub-domain S in order to match the second partition. The framework will provide a set of predefined constructs for common redistribution maps while the users will provide their own for more specific patterns. Some simple redistribution patterns that can be easily provided by the framework are:
• rebalance() : Redistribute the N elements of the pContainer across P locations such that each location will own N/P elements
pContainer by cyclically rotating them a given number of locations in a given direction.
• custom redistribution for certain pContainers: transpose for two dimensional containers, graph redistributions, etc.
1. Data Marshaling
To support the default redistribution, the framework requires that both pCont- ainer data elements and bContainers be marshaled. Support for data marshaling is provided by the stapl RTS[54] and requires users to implement a define type() method as part of the class that needs to be marshaled. The bContainer interface includes the define type as part of its required interface. This can easily be achieved as stapl provides built in support for all stl containers and these are the building blocks for most bContainers we employ in our pContainers.
In Figure 14 we include examples showing the define type() implementation for some simple classes and for the pArray bContainer. The method receives as input an object of type stapl::typer. Subsequently, the typer is made aware of all the class data members and this process continues in a recursive fashion. In Figure 14(a), class classB has as a data member an object of classA so the define type of classB will recursively invoke the define type of it. In Figure 14(b), we show the define type for the pArray bContainer which invokes recursively the define type of the stl valarray data member.
With bContainer marshaling support available, the pContainer redistribution implementation is greatly simplified. The redistribution map specifies the sub-domains and their new locations. Data corresponding to sub-domains is appropriately packed in bContainers and shipped to the destination
1 c l a s s c l a s s A { 2 int a ; 3 double b [ 1 0 ] ; 4 void d e f i n e t y p e ( t y p e r&t ){ 5 t . member ( a , 1 0 ) ; 6 t . member ( b ) ; 7 } 8 } 9 c l a s s c l a s s B { 10 ob ject A a ; 11 void d e f i n e t y p e ( t y p e r&t ){ 12 t . member ( a ) ; 13 } 14 }
(a) Simple classes
1 template<c l a s s T> 2 c l a s s p a r r a y b c o n t a i n e r { 3 s t d : : v a l a r r a y <T> m data ; 4 // s p e c i f i c i n t e r f a c e . . . 5 6 void d e f i n e t y p e ( t y p e r&t ){ 7 t . member ( a ) ; 8 } 9 } (b) pArray bContainer
Fig. 14. Marshaling interfaces.