When building a pContainer, a developer has the ability to customize the pContainer main functional modules as described in Chapter IV, Section B. For example, a developer may want to use a certain storage or certain partition and mapping on the machine, enforce a certain memory consistency model, or enable/disable thread safety, etc. This leads us to design the PCF in a very configurable way where users can select individual functional modules. This is accomplished using traits classes that are passed as template arguments to pContainer base classes. The traits can be customized by developers and end users for classes of pContainers or even on a per pContainer instance.
In addition to the data structure specific arguments, all pContainer classes take as template arguments the partition and the pContainer traits. For example, in
1 // t h e STAPL P a r a l l e l Array D e f i n i t i o n 2 template<typename T, 3 typename P a r t i t i o n=p a r t i t i o n b a l a n c e d <>, 4 typename T r a i t s=p a r r a y t r a i t s > 5 c l a s s p a r r a y : public p c o n t a i n e r i n d e x e d <Tr a i s > { . . . } 6 7 // t h e STAPL P a r a l l e l Graph D e f i n i t i o n 8 template <g r a p h a t t r i b u t e s D, g r a p h a t t r i b u t e s M, 9 typename VertexP = n o p r o p e r t y , 10 typename EdgeP = n o p r o p e r t y , 11 typename P a r t i t i o n=p a r t i t i o n r e l a t i o n , 12 typename T r a i t s = p g r a p h t r a i t s > 13 c l a s s p graph : public p c o n t a i n e r r e l a t i o n <T r a i t s > { . . . }
Fig. 15. pContainer template arguments.
Figure 15 we list the definition of the pArray and pGraph; more detail on these specific data structures is provided in Chapter IX and XI, respectively:
The partition specifies the GID, domain, bContainer, and thread safety manager. The pContainer will use the definition for these types from the partition. The pContainertraits can be used to specify lower level details such as partition mapper, data-distribution-manager and location-manager. We expect these to be less often customized by users than the storage and partition.
When interacting with the framework users can provide alternative implementa- tions for domain, partition, bContainer, partition mapper and location-manager using the template arguments. The custom provided modules need to implement the required interfaces as specified in Sections B and D.
In Figure 16 we show an example of stapl pseudocode illustrating how users can customize an existing pGraph implementation. Users can select the storage by providing the type of an existing bContainer and similarly for the partition. Figure 16, line 5, shows the declaration of a directed pGraph allowing multiple edges between
1 // b c o n t a i n e r d e f i n i t i o n : 2 // s e q u e n t i a l graph u s i n g v e c t o r s t o r a g e 3 typedef p g b a s e c o n t a i n e r <v e c t o r ,> b p g s ; 4 // and a s t a t i c p a r t i t i o n 5 typedef p g s t a t i c <bpg s , . . . > p a r t i t i o n s ; 6 7 // p a r a l l e l graph u s i n g s t d : : map s t o r a g e 8 typedef p g b a s e c o n t a i n e r <map , . . . > bpg d ; 9 // and a dynamic p a r t i t i o n 10 typedef pg fwd<bpg d , . . . > p a r t i t i o n d ; 11 12 // pgraph w i t h s t a t i c p a r t i t i o n 13 p graph<DIRECTED, MULTI, p a r t i t i o n s > p g s (N ) ; 14 // pgraph w i t h dynamic s t o r a g e and
15 // method f o r w a r d i n g
16 p graph<DIRECTED, MULTI, p a r t i t i o n d > pg d (N ) ;
Fig. 16. pGraph customization.
the same source and a target vertex and using a static partition. With a static partition, users need to declare the size of the pGraph at the construction time and subsequent invocations of the add vertex method will trigger an assertion. Figure 16, line 6, shows the declaration of a pGraph using a dynamic partition that allows for addition and deletion of both vertices and edges. More details and performance results regarding the benefits of having different partitions and types of storage are discussed in Chapter XI, Section F.2 in the context of a dynamic pGraph data structure.
CHAPTER VI
THREAD SAFETY
In this chapter, we describe the infrastructure provided by the pContainer framework to implement thread safe pContainers. The goal of STAPL is to allow users to easily develop thread safe containers while giving them the possibility to override the default locking policies implemented by the framework. We define that a pContainer is thread safe [33, 34, 35] if concurrent method invocations from various threads are perceived as being atomic thus always leaving a pContainer in a consistent state.
We start by first motivating the need for thread safety. Data stored in pContainers is accessed by pAlgorithms and at this level stapl employs the task dependency graph (TDG) to encode data dependences across various tasks of a computation. However there are a large number of parallel algorithms employing commutative tasks. In this case, two tasks A and B are safe to be executed in A → B order (A followed by B) or B → A but not A||B (A in parallel with B). For such scenarios the dependencies between two tasks can be eliminated under certain conditions as long as atomicity of the pView and pContainer method invocations are guaranteed. As a simple example consider the sample sort parallel algorithm where each task inserts elements from an input pArray into a pArray of pVectors (buckets). This computation can be expressed as a no dependency TDG where each task determines the bucket an element belongs to and inserts the element into that bucket. This algorithm will properly insert all the elements into buckets as long as atomicity at the bucket level is guaranteed.