---
title: 'Mapple: Declarative DSL for Distributed Mapping'
url: https://www.emergentmind.com/topics/mapple
type: topic
---

# Mapple: Declarative DSL for Distributed Mapping

Searching arXiv for the exact “Mapple” paper and closely related mapping/runtime context.
First, I’ll fetch the exact “Mapple” paper and then a couple of closely related runtime/mapping references for context.
Mapple is a domain-specific language for mapping distributed heterogeneous parallel programs. It is designed for task-based programming systems running on distributed heterogeneous machines, where performance depends on how a multi-dimensional iteration space is assigned to a structured processor space such as nodes \(\times\) GPUs-per-node. In the paper’s formulation, Mapple is a high-level, declarative programming interface for mapping distributed applications, implemented on top of the Legion runtime by translating Mapple mappers into Legion’s low-level C++ mapper interface. It is therefore not a replacement runtime, and it is not about generic “maps” or key-value systems; it is a higher-level mapping layer for distributed task-based execution [2507.17087].

## 1. Scope, problem setting, and conceptual role

Mapple targets mapping decisions in distributed applications on heterogeneous machines. In this setting, an application exposes a logical iteration space, often multi-dimensional, while the machine exposes a structured processor space that may itself be multi-dimensional because the hardware is hierarchical. The paper emphasizes that these two spaces often differ in dimensionality as well as size, and that poor alignment increases communication, harms locality, and can trigger out-of-memory behavior by forcing data materialization in inappropriate memories. Within this framework, “mapping” includes how to partition and distribute loops across distributed machines, where to place data in memory, how to lay out data in memory, whether to perform garbage collection, and how to make scheduling decisions [2507.17087].

The paper positions Mapple against three existing interface styles. Enumeration-based interfaces explicitly list tile-to-processor assignments and are expressive but not general. Keyword-based interfaces offer predefined distributions such as block or cyclic and are easy to use but too restrictive. Programmatic interfaces, including those in Chapel and Legion, are flexible but low-level and runtime-centric. The critique is concrete: such interfaces fragment mapping logic across runtime stages and require expertise in runtime internals. Mapple’s response is to centralize mapping logic in a declarative DSL whose main abstraction is transformation of processor spaces rather than direct manipulation of low-level mapper callbacks [2507.17087].

A common misconception is to treat Mapple as a portability layer across runtimes. The paper states that portability across runtimes is explicitly a non-goal. Its implementation target is Legion, and its practical contribution is a higher-level mapping interface over Legion’s existing low-level C++ machinery, not a universal mapping language for all task-based systems. This suggests that the paper’s main claim is about abstraction level and mapping expressiveness, rather than runtime independence [2507.17087].

## 2. Language design and mapping model

Mapple is presented as a declarative DSL in which mapping is expressed through a combination of task placement, data placement, layout constraints, and user-defined mapping functions. The simplified grammar in the paper includes statements of the forms `TaskMap`, `DataMap`, `DataLayout`, `FuncDef`, and `IndexTaskMap`, together with processor classes `CPU`, `GPU`, and `OMP`, memory classes `SYSMEM`, `FBMEM`, and `ZCMEM`, and layout constraints such as `SOA`, `AOS`, `C_order`, `F_order`, and `Align == int` [2507.17087].

The most characteristic part of the language is its support for explicit transformations on a logical processor space. Rather than forcing the programmer to directly author separate low-level sharding and mapping callbacks, Mapple allows the programmer to first transform the processor space and then write concise functions from iteration points to processors. A representative example in the paper is:

```python
m = Machine(GPU)
def block2d(Tuple point, Tuple space):
    idx = point * m.size / space
    return m[*idx]
IndexTaskMap loop0 block2d
Region task_init arg0 GPU FBMEM
Layout task_finish arg1 CPU C_order
GarbageCollect systolic arg2
Backpressure systolic 1
```

This example defines the GPU machine space, specifies a 2D block mapping by tuple arithmetic, and separately declares region placement, memory layout, garbage collection, and scheduling behavior. The paper contrasts this with the corresponding Legion C++ mapper, where the same logical intent is scattered across sharding and mapping APIs and accompanied by substantial omitted boilerplate [2507.17087].

The paper’s central abstraction is therefore not a new execution model, but a new way to describe mapping in terms of high-level processor-space transformations. This is especially important when the iteration space of the computation and the processor hierarchy of the machine do not align naturally. A plausible implication is that Mapple aims to make mapping logic compositional: the programmer can first normalize the processor space to match the structure of the computation, and only then define the index mapping itself [2507.17087].

## 3. Transformation primitives over processor spaces

Mapple’s core primitives are `split`, `merge`, `swap`, `slice`, and `decompose`. These are transformations over the processor space, not loop transformations over the computation. Their purpose is to resolve mismatches between the structure of the iteration space and the structure of the hardware [2507.17087].

| Primitive | Effect | Note |
|---|---|---|
| `split` | Increases dimensionality by splitting one processor dimension | Used to refine a coarse hierarchy |
| `merge` | Fuses two processor dimensions into one | Used to flatten hierarchy |
| `swap` | Exchanges two processor dimensions | Reorders hierarchy axes |
| `slice` | Restricts mapping to a subset of processors | Selects a processor subspace |
| `decompose` | Expands one dimension into multiple factors | Chooses factors to minimize communication |

For `split`, if \(m\) has shape \((s_0,\dots,s_{n-1})\), then splitting dimension \(i\) by factor \(d\) produces shape \((s_0,\dots,d,s_i/d,\dots,s_{n-1})\). The semantics are given by a mapping from indices in the transformed space \(m'\) back to indices in the original space \(m\), so the transformation is invertible at the index level. `merge` performs the opposite structural operation, combining two processor dimensions into one. `swap` permutes processor dimensions, and `slice` selects a bounded subrange of a given dimension, which the paper notes is useful for mapping work to a subset of processors [2507.17087].

The significance of these primitives is clearest in irregular mappings that keyword-based interfaces cannot express. The paper gives a custom cyclic distribution example where a 2D processor space is first flattened to 1D with `merge`, a 2D iteration point is linearized, and round-robin assignment is then applied over the flattened processors. This is concise in Mapple but not expressible in fixed keyword systems. The paper also gives a 2.5D matrix multiplication example in which a 3D iteration space is mapped onto an initial 2D processor space by repeated `split` operations, effectively turning a 2D machine hierarchy into a 6D transformed processor space. These examples motivate the need for more principled dimensionality-resolution primitives, especially `decompose` [2507.17087].

## 4. `decompose` and communication-aware dimensionality resolution

The paper identifies `decompose` as its key new primitive. Conceptually, if a processor-space dimension \(d_i\) must be expanded into \(k\) dimensions to align with \(k\) iteration dimensions, `decompose` chooses how to factor \(d_i\) into integers:
$$
M' = M.\mathtt{decompose}(i, (l_1, \ldots, l_k)),
$$
subject to
$$
\prod_{m=1}^{k} d_{i_m} = d_i.
$$
The arguments \((l_1,\ldots,l_k)\) are the relevant iteration-space extents. The paper states that `decompose` is shorthand for repeated `split`, but its importance lies in how the split factors are chosen [2507.17087].

The optimization objective is communication-aware. The paper defines the problem as
$$
\begin{aligned}
\text{minimize} \quad & \sum_{m=1}^{k} \frac{d_{i_m}}{l_m} \\
\text{subject to} \quad & \prod_{m=1}^{k} d_{i_m} = d_i, \quad d_{i_m} \in \mathbb{N} \;\; \forall m.
\end{aligned}
$$
Introducing workloads
$$
w_m = \frac{l_m}{d_{i_m}} \qquad (1 \le m \le k),
$$
the optimization becomes
$$
\begin{aligned}
\text{minimize} \quad & \sum_{m=1}^{k} \frac{1}{w_m} \\
\text{subject to} \quad & \prod_{m=1}^{k} w_m = \frac{\prod_{m=1}^{k} l_m}{d_i}, \quad \frac{l_m}{w_m} \in \mathbb{N} \;\; \forall m.
\end{aligned}
$$
The communication argument is based on the surface area of local rectangular partitions. If each processor handles a block with extents \((w_1,\ldots,w_k)\), then the hyperrectangle surface area is
$$
SA(x_1, x_2, \ldots, x_k) = 2 \cdot \left( \prod_{m=1}^{k} x_m \right) \cdot \left( \sum_{m=1}^{k} \frac{1}{x_m} \right).
$$
Since the local block volume is fixed for fixed iteration size and processor count, minimizing communication reduces to minimizing \(\sum_m 1/w_m\). Using AM–GM, the paper argues that communication is minimized when the per-dimension workloads are as balanced as possible [2507.17087].

This formalism explains why `decompose` can outperform earlier dimensionality-resolution heuristics. The paper compares it to a prior heuristic, based on Chapel’s documented strategy, that factors the processor count into a “balanced” grid without considering iteration-space aspect ratio. For 6 processors and a 2D iteration space, that heuristic picks \((3,2)\) regardless of whether the iteration-space shape is \((12,18)\) or \((18,12)\). The paper shows this can be suboptimal: for the former case, communication is 96 elements, whereas a shape-aware choice \((2,3)\) reduces it to 84. The implementation of `decompose` uses exhaustive search over valid factorizations, which the paper argues is tractable in practice because machine sizes and dimensionalities are small, exponents are typically below 10, and \(k \le 3\) in many use cases [2507.17087].

## 5. Implementation on Legion and runtime interpretation

Mapple is implemented on top of Legion by compiling high-level Mapple mappers into Legion’s low-level C++ mapping interface. The paper’s claim is therefore not that Mapple replaces Legion, but that it offers a better authoring layer over Legion’s approximately 7,000-line mapper interface [2507.17087].

The runtime-semantics discussion explains why this matters. In Legion’s low-level model, tasks progress through stages such as enqueued, mapped, launched, and executed, with transition judgments over task trees, dependencies, and sibling order. The user-visible mapping functions include `SHARD`, which decides node-level distribution of index tasks, and `MAP`, which decides processor-level placement within a node. Mapple’s key observation is that, although Legion exposes these as separate low-level callbacks, they can be unified at a higher level as one mapping from iteration space to processor space. Translation then lowers that unified view back into the corresponding callback implementations expected by Legion [2507.17087].

The lowering strategy is described at a high level. The compiler or interpreter evaluates the user’s Mapple function per iteration point, applies the selected sequence of invertible processor-space transformations, computes coordinates in the original `Machine(...)` space, and returns these coordinates as the node identifier for `SHARD` and the processor identifier for `MAP`. This suggests that Mapple’s abstraction boundary is centered on index mapping rather than on scheduler internals. It preserves Legion compatibility while hiding the fragmentation of mapping logic across runtime stages [2507.17087].

The paper also uses this setting to motivate Mapple’s critique of low-level programmatic interfaces. Chapel’s mapper authoring is described as requiring 19 functions and 33 pages of documentation, and Legion’s interface is similarly presented as flexible but coupled to internal abstractions. Mapple’s significance in this context is that it centralizes mapping logic in a single high-level description, while still being expressive enough to cover custom cyclic mappings, hierarchical matrix multiplication layouts, memory placements, and data layout directives [2507.17087].

## 6. Evaluation, performance, and limitations

The evaluation uses a distributed cluster in which each node has 40 IBM Power9 CPU cores and 4 NVIDIA V100 GPUs, connected by NVLink 2.0 within a node and InfiniBand EDR across nodes. Measurements are averaged over five runs. The benchmarks comprise nine applications: six distributed matrix multiplication algorithms—Cannon, SUMMA, PUMMA, Johnson, Solomonik, and COSMA—and three scientific workloads: Circuit, Stencil, and Pennant [2507.17087].

The productivity result is explicit. Across the nine applications, the average mapper shrinks from 406 lines of C++ to 29 lines in Mapple, a 14× reduction on average, with per-benchmark reductions ranging from 11× to 24×. The paper also states that these shorter mappers make identical mapping decisions to the original C++ mappers and show no observable overhead. On performance, tuned Mapple mappers achieve up to 1.34× improvement over expert-written C++ mappers, with the paper noting values including 1.34×, 1.31×, and several around 1.07×–1.09×. For the six matrix multiplication benchmarks, the gains come entirely from better index mappings; for Circuit, Stencil, and Pennant, gains come from different memory assignments enabled by `DataMap` and `DataLayout` [2507.17087].

The paper also presents a dedicated study of `decompose` on 2D stencil workloads across 180 configurations varying aspect ratio from \(1{:}1\) to \(1{:}32\), area per node from \(10^6\) to \(4 \times 10^8\), and number of GPUs from 4 to 128. Compared with the prior heuristic, `decompose` yields improvements ranging from 0% to 83%, with a geometric mean improvement of 16%; in the abstract and conclusion this is summarized as up to 1.83× over existing dimensionality-resolution heuristics. The largest gains occur for highly skewed aspect ratios, where the previous heuristic assumes processor grids should be balanced independently of input shape. The improvement rises from 7% at \(1{:}1\) to 27% at \(1{:}32\), while it drops from 32% to 5% as area per node increases because communication becomes a smaller fraction of total cost [2507.17087].

The paper is also clear about limitations. Portability across runtimes is a non-goal. The formal development of `decompose` assumes communication patterns that can be modeled by block partitions and boundary surface area; extensions to anisotropic halos and transpose-style all-to-all communication are discussed, but framed as extensions rather than the main evaluated path. The search-based `decompose` algorithm is tractable because the relevant dimensionalities and factor exponents are small. More broadly, Mapple is aimed at programmers using Legion-like task-based distributed runtimes who need more control than keyword distributions provide, but who want to avoid authoring large callback-heavy C++ mappers. Within that scope, the paper’s principal contribution is a declarative mapping DSL whose main abstraction is transformation of processor spaces, together with a communication-minimizing dimensionality-resolution primitive and an implementation that materially reduces mapper complexity while preserving or improving performance [2507.17087].

Source: https://www.emergentmind.com/topics/mapple