POOMA banner

Layouts and related classes:


All POOMA data objects that use the MultiPatchEngine will use one of the Layout classes to define how the data patches are organized. Layouts define how the data object is sub-divided into 'patches', a single contiguous region of memory. Most Layouts also provide for GuardLayers definitions.

The following is a code fragment illustrating the creation of a POOMA Array using a GridLayout.

  IndirectionList<int> g1(5);
  g1(0) = 0; g1(1) = 5; g1(2) = 11; g1(3) = 17; g1(4) = 25;
   Interval<1> dom(g1(0),g1(4)-1);

  GridPartition<1> martition(Grid<1>(g1),igl,egl);
  GuardLayers<1> igl(1), egl(0,2);
  GridLayout<1> mayout2(dom, martition, ReplicatedTag() );
  Array<1, double, MultiPatch<GridTag, Brick> > aa(mayout2);


The GuardLayers<Dim> class is used to specify both internal and external guard layers. Each dimension has a pair of integers to allow for asymmetric guard layer thicknesses. External guard layer specifications override those specified by the internal guard layer for those patches that make up the edges of the data object.

There are two types of GuardLayers used by a MultiPatchEngine based Pooma data object. These are internal guard layers and external guard layers. Each data patch of a POOMA data object has its domain extended by the number of data elements specified by the GuardLayers object.

Internal guard layers are layers of elements or cells added to the upper and/or lower end of the sub-domain of the PatchEngine.  These cells are to be filled with the data values of the adjacent patches, in order to minimize cross context data dependency of execution of expressions for each PatchEngine. In general it is an error to specify a internal guard layer that is larger than the patch dimension. This is especially important to remember when dealing with SparseTileLayout and GridLayout.

External guard layers are on the edge of the entire data object and are used for external boundary conditions. In this diagram, the external guard layers are indicated by 'egl'. External guard layers data allocation exists only for those PatchEngines that are on the edges of the full domain of the Pooma data object. The data elements that make up the external guard layers are generally used for external boundary conditions.

In this example, the GuardLayers specification is symmetric, and the size of the internal and external guard layers are both 2. In general, GuardLayers may be specified asymmetrically, for instance:

GuardLayers<2> egl(0,5,3,1);

The first axis has an (external) GuardLayers specification that is 0 on the lower edge of the domain, and has a width of 5 on the upper edge of the domain, while in the second axis, the lower edge of the domain is extended by 3, and extended by 1 on the upper edge of the domain.

When the external guard layers and internal guard layers are specified separately, the thickness of the external guard layer region in the patches that form the edges of the domain will be that which was specified by the external guard layer. Where those patches don't have an edge on the border of the domain, the internal guard layer specification will determine the size of the patches.

illustration of internal and
external guard cells

The following graphic illustrates the internal and external guard cell regions for a UniformGridLayout with asymmetric guard cell specifications:

GuardLayers egl(1,3,2,3);
GuardLayers igl(2,1,1,3);
Interval<2> dom(Interval<1>(0,14),Interval<1>(0,9));
UniformGridPartition<2>  asypart(Loc<2>(3,2),igl,egl);
Array<2,double,MultiPatchEngine<UniformTag,CompressibleBrick> >     Array(UniformGridLayout<2>(dom,asypart,ReplicatedTag());
2x3 patch asymetric guard cell


The currently existent Layouts are:

Divides the data space into regions defined by dividing each axis into an integral number of equally size segments.

Divides the data space into regions by segmenting each axis arbitrarily.


Tiles the domain (called the BoundingBox for this Layout) with non-overlapping patches. The patches do not have to completely tile the BoundingBox. The SparseTileLayout was designed in anticipation of Adaptive Mesh Refinement codes development within Pooma. In SparseTileLayout, there are class member functions that support accessing both the list of conventional internal and external guard layer regions, as well as guard layers that do not intersect or overlap onto the data space of patches defined within the layout.


An inherently 1-dimensional Layout, that allows the patches to be resized.


A single patch domain defined by a single Interval.

UniformGridLayout, GridLayout and SparseTileLayout

The UniformGridLayout, GridLayout, and SparseTileLayout all have a trailing tag argument on most of their constructors that specifies how the data is ContextMappered. These tags are ReplicatedTag and DistributedTag. If ReplicatedTag is specified, then LocalMapper is used, while if DistributedTag is specified, then the DistributedMapper is used. All of the aforementioned layouts have the default constructor that doesn't require the use of the ReplicatedTag or DistributedTag. A constructor having the form (Domain,Partitioner, ContextMapper) doesn't require the use of the trailing tags since it explicitly specifies a ContextMapper.


Layouts have Partitioners that are invoked to generate the patch-subdomains, taking into account internal and external GuardLayers.

The currently available Partitioners are

Used to generate patches for a UniformGridLayout.

Used to generate patches for a GridLayout.

Generates patches from a provided list of domains.

Generates a list of empty patches that correspond in context and affinity to the patch list of a provided reference Layout. Generally used with DynamicLayout.

ContextMapper and derived classes

Once the patch lists have been generated, the assignment of the context and affinity values of each of the patches is determined by the ContextMapper. The ContextMapper class is a base class of a set of derived mappers specialized for particular data-distributed or data-replicated data objects.

Assigns all patches to a Context == -1. The value -1 is a special value used by other parts of POOMA to indicate that the entire data object should be replicated on each context.

The DistributedMapper is a wrapper for other ContextMappers that tries to pick an optimal mapper for the case where the data is distributed over multiple contexts.

This is a mapper specialized to Dim == 1, and evenly divides the patch list sequence into the number of contexts.


Uses Recursive bisection of the largest group of patches to produce contexts with an approximately minimum surface to volume ratio. See figure.


Assigns patches to a context in a modified Fortran storage order: As the index gets to an boundary, the lowest axis index decrements, rather than going from LowIndex = IndexMax to LowIndex = 0; see the figure for an illustration of this mapper.

contiguous mapper

Restrictions on combinations of Layouts, Partitioners, and ContextMappers.

Only some combinations of Layouts, Partitioners and ContextMappers are valid.

It is a logical error to use a GridPartitioner or SpatialPartitioner with a UniformGridLayout, as one of the optimizations within UniformGridLayout is that all domains are the same size. However, you can use a UniformGridPartitioner with a GridLayout, as the partitioning performed is within the restrictions imposed by GridLayout. SparseTileLayout is only compatible with TilePartition.

It is an error to try to use a MultiPatch engine of Brick or CompressibleBrick with any other mapper other than LocalMapper, and/or any layout that is not constructed with a ReplicatedTag argument. Since Bricks are single context only data engines, any MultiPatch engine constructed using Brick patch engines must not be distributed.

Similarly, MultiPatchEngine may not be constructed with the PatchEngine tag specified as Remote<PatchEngine> if LocalMapper is specified in the Layout used to construct the MultiPatchEngine. Either of the aforementioned combinations will generate a PInsist error inside MultiPatchEngine.