Single-program multiple-data (SPMD) runs the same program on multiple devices while each device processes a different chunk of data. In JAX, pmap() expresses this model: it compiles a function with XLA, replicates it across devices, and executes the replicas in parallel. section 7.0 section 7.1.2
SPMD resembles vmap() because both map a function over array axes, but they parallelize at different levels. vmap() adds a batch dimension to primitive operations, whereas pmap() distributes replicas across devices. Functional purity makes these transformations composable, so a pipeline can combine compilation, vectorization, parallelization, and differentiation. section 7.1.2 section 1.2.2
Use SPMD when the computation naturally divides across devices:
- Split input data into one leading slice per device; pmap() expects that mapped axis to match the available device count. section 7.1.2
- Keep the same model or computation on every device when using data parallelism. section 7.3
- Communicate and aggregate results such as gradients when replicas must update identical model weights. section 7.3
- Expect sublinear scaling because communication between devices adds overhead. section 7.0
Mapping a dot product across eight devices
For ten million pairs of three-dimensional vectors, reshape each input from (10000000, 3) to (8, 1250000, 3). Applying pmap(dot) produces one result per device with shape (8,), while pmap(vmap(dot)) processes every local batch and produces (8, 1250000). Flattening that result gives (10000000,), and comparing it with the vmap() result returns Array(True). Applying pmap() directly to the original arrays instead requests ten million logical devices and raises a device-count ValueError.
Listing 7.5 Applying vmap and pmap to our arrays
dot_batched = jax.jit(jax.vmap(dot)) #1 x_vmap = dot_batched(v1s, v2s) #2 x_vmap.shape #3 >>> (10000000,) #3 dot_parallel = jax.pmap(dot) #4 x_pmap = dot_parallel(v1s,v2s) #5 >>> ... >>> ValueError: compiling computation that requires 10000000 logical devices, but only 8 XLA devices are available (num_replicas=10000000) #6
Inspect the runnable comparison showing why pmap() requires an input mapping axis aligned with the available devices. section 7.1.2
