---
title: 'BabelStream: GPU Memory Bandwidth Benchmark'
url: https://www.emergentmind.com/topics/babelstream
type: topic
---

# BabelStream: GPU Memory Bandwidth Benchmark

BabelStream is the open-source successor to the classic GPU-STREAM benchmark suite. Its stated role is to drive large, cache-bypassing workloads against device HBM, or global memory, and to measure achievable copy bandwidth without the noise of PCIe transfers. In the cited studies, it appears in two closely related but distinct roles: as the HIP-based bandwidth source used to construct an instruction roofline model for AMD GPUs, and as a memory-bound benchmark used to evaluate MLIR-based GPU code generation in Mojo on NVIDIA H100 and AMD MI300A systems [2110.08221], [2509.21039].

## 1. Benchmark definition and scope

BabelStream is characterized as a bandwidth benchmark rather than a full application surrogate. In the AMD instruction-roofline study, its “sole job” is to drive large, cache-bypassing workloads against HBM and to report sustained bandwidth from the canonical `copy` kernel. Because it does not attempt to include any CPU-GPU transfer overhead, its bandwidth numbers are presented as closely approximating the true HBM bandwidth that a well-tuned HPC kernel could achieve on the measured devices [2110.08221].

This scope is narrow by design. BabelStream is described as strictly measuring global-HBM throughput, not stressing intra-chip shared or texture caches, and therefore not replacing a full cache hierarchy analysis. The same narrowness is also what makes it useful in roofline construction and in language-comparison studies: it isolates global-memory behavior and reduces confounding factors that would otherwise complicate interpretation [2110.08221].

## 2. Kernel repertoire and execution model

In the Mojo study, BabelStream is exposed as five fundamental array-kernel operations: Copy, Mul, Add, Triad, and Dot. The first four are global-memory kernels; the Dot kernel is a reduction. The benchmark is thus not limited to a single bandwidth number, even though some studies use only the canonical `copy` kernel for roofline calibration [2509.21039].

| Kernel | Operation | Bandwidth expression |
|---|---|---|
| Copy | `c[i] = a[i]` | $B_{\mathrm{Copy}} = 2 \cdot B_{\mathrm{array}}$ |
| Mul | `b[i] = scalar * c[i]` | $B_{\mathrm{Mul}} = 2 \cdot B_{\mathrm{array}}$ |
| Add | `c[i] = a[i] + b[i]` | $B_{\mathrm{Add}} = 3 \cdot B_{\mathrm{array}}$ |
| Triad | `a[i] = b[i] + scalar * c[i]` | $B_{\mathrm{Triad}} = 3 \cdot B_{\mathrm{array}}$ |
| Dot | reduction of $\sum a[i]\cdot b[i]$ | $B_{\mathrm{Dot}} = 2 \cdot B_{\mathrm{array}}$ |

The Mojo implementation makes the execution structure explicit. Global-memory kernels are written as direct index computations of the form `var i = block_idx.x * block_dim.x + thread_idx.x`, followed by a single elementwise store. The Dot kernel uses GPU shared memory through `stack_allocation[..., address_space = AddressSpace.SHARED]` and performs a two-level tree reduction with `barrier()`. Kernel launches use `DeviceContext.enqueue_function` with `grid_dim` and `block_dim` parameters [2509.21039].

## 3. Measurement model and derived metrics

Two quantitative frameworks are attached to BabelStream in the cited work. In the Mojo study, the benchmark is analyzed with direct bandwidth formulas. Let $N$ be vector length, $T = \mathrm{sizeof}(\mathrm{element})$, and $t$ the kernel time. Then
$$
B_{\mathrm{array}} = \frac{N \cdot T}{t},
$$
with kernel-specific byte-transfer factors:
$$
B_{\mathrm{Copy}} = 2 \cdot B_{\mathrm{array}}, \quad
B_{\mathrm{Mul}} = 2 \cdot B_{\mathrm{array}}, \quad
B_{\mathrm{Add}} = 3 \cdot B_{\mathrm{array}}, \quad
B_{\mathrm{Triad}} = 3 \cdot B_{\mathrm{array}}, \quad
B_{\mathrm{Dot}} = 2 \cdot B_{\mathrm{array}}.
$$
The quantity $B_{\mathrm{peak}}$ is the theoretical device bandwidth in GB/s, and $B_{\mathrm{achieved}}$ is the bytes transferred divided by kernel time [2509.21039].

In the AMD instruction-roofline study, BabelStream supplies the sustainable HBM bandwidth that defines the memory roof, while ROCProfiler supplies instruction and memory-byte counters. The raw counters are `SQ_INSTS_SALU`, `SQ_INSTS_VALU`, `FETCH_SIZE`, `WRITE_SIZE`, and kernel runtime. These are combined into three derived metrics:
$$
\mathrm{instructions} = 4 \times \mathrm{SQ\_INSTS\_VALU} + \mathrm{SQ\_INSTS\_SALU},
$$
$$
II = \frac{\mathrm{instructions}/64}{(\mathrm{bytes\ read} + \mathrm{bytes\ written}) \times \mathrm{runtime}},
$$
$$
GIPS_{\mathrm{achieved}} = \frac{\mathrm{instructions}/64}{10^9 \times \mathrm{runtime}},
$$
and
$$
GIPS_{\mathrm{peak}} = CU \times \frac{\mathrm{WFS}}{\mathrm{CU}} \times IPC \times f_{\mathrm{GHz}}.
$$
For MI60 and MI100, the study specifies $CU = 64$ and $CU = 120$, respectively, with one wavefront scheduler per CU and $IPC = 1$. The factor of $64$ is the wavefront normalization required on these AMD HPC GPUs, and each `SQ_INSTS_VALU` count is multiplied by $4$ because each VALU counter represents one SIMD that executes 4 vector lanes [2110.08221].

## 4. BabelStream in AMD instruction roofline construction

The AMD roofline workflow integrates BabelStream directly into model construction. The authors checked out the HIP implementation of BabelStream at commit `5182342` under ROCm `4.1.1` on an AMD early-access Frontier prototype, compiled and ran the canonical `copy` kernel, and converted the sustained bandwidth from MB/s to GB/s for roofline plots. On the profiling side they used ROCProfiler at commit `759f081` to collect `SQ_INSTS_*` and `FETCH/WRITE_SIZE`, and the roofline plotting was based on NERSC’s Python scripts modified to take bytes and GIPS [2110.08221].

The instruction roofline is defined with instruction intensity $II$ on the horizontal axis and achieved GIPS on the vertical axis. The compute roof is a flat line at $GIPS_{\mathrm{peak}}$, while the memory roof is a slanted line:
$$
GIPS = \mathrm{BW}_{\mathrm{HBM}} \times II.
$$
Here $\mathrm{BW}_{\mathrm{HBM}}$ is the copy bandwidth measured by BabelStream in bytes per second. Points below the slanted line are interpreted as memory-bound, points below the flat compute line as compute-bound, and the intersection is the “knee,” or balance point [2110.08221].

The reported BabelStream `copy` bandwidths are approximately `808 975 MB/s` for MI60, or about `0.809 TB/s`, corresponding to roughly `81%` of the theoretical `1 TB/s`, and approximately `933 356 MB/s` for MI100, or about `0.933 TB/s`, corresponding to roughly `78%` of the theoretical `1.2 TB/s`. The study states that the memory-roofline slope obtained from BabelStream closely tracks the theoretical HBM rate, that omitting PCIe overhead yields a clean slope directly comparable to HBM-only workloads, and that the reproducibility of copy-bandwidth results across devices gave confidence in placing the AMD memory boundary in the instruction roofline [2110.08221].

This calibration was then applied to PIConGPU. The profiled kernels were `MoveAndMark` and `ComputeCurrent`, described as the two heaviest kernels in the LWFA and TWEAC science cases and together accounting for more than `75%` of runtime. For the LWFA `ComputeCurrent` kernel, the reported single-wavefront point is: V100 with peak GIPS of about `489.6`, achieved GIPS of about `2.18`, instruction intensity of about `0.006 inst/byte`, and time of about `4 ms`; MI60 with peak GIPS of about `115.2`, achieved GIPS of about `0.62`, instruction intensity of about `0.398`, and time of about `12.7 ms`; and MI100 with peak GIPS of about `180.24`, achieved GIPS of about `2.856`, instruction intensity of about `1.863`, and time of about `2.5 ms`. For TWEAC `ComputeCurrent`, the ordering in execution time is similar, with MI100 fastest at `0.246 s`, MI60 slowest at `0.394 s`, and achieved GIPS highest on V100 at `6.63 GIPS` versus `4.99 GIPS` on MI100. The study concludes that MI100 attains similar or better execution time than V100 for kernels of interest, but that profiling tool differences make direct architectural comparison difficult; MI60 shows the worst performance among the three GPUs in execution time, GIPS, and instruction intensity [2110.08221].

## 5. MLIR lowering and performance portability

The Mojo study uses BabelStream as a memory-bound workload to test whether an MLIR-based language stack can preserve vendor-level global-memory behavior. The lowering path is described in detail: the Mojo front end lowers the Mojo AST into MLIR Standard and GPU dialects; `UnsafePointer` becomes an MLIR `memref` with `address_space 1` for global memory; `stack_allocation[..., AddressSpace.SHARED]` becomes an MLIR `llvm.alloc` in `address_space 3`; `thread_idx` and `block_idx` map to `gpu.thread_id` and `gpu.block_id`; `barrier()` maps to `gpu.barrier`; and `memref.load/store` is lowered to GPU global-load (`ld.global`) and store (`st.global`) instructions through the NVVM or ROCDL backend. Final lowering proceeds through NVVM for NVIDIA or ROCDL for AMD to PTX or AMDGPU ISA while preserving coalesced loads and stores [2509.21039].

The reported experimental configuration for BabelStream in Mojo is $N = 2^{25} \simeq 33.5$ million elements, `dtype=float32`, and `grid_dim` chosen to fill the device. On NVIDIA H100, where $B_{\mathrm{peak}} = 3900$ GB/s, the measured results are: Copy at `3600 GB/s` (`92%` of peak) for Mojo versus `3550 GB/s` (`91%`) for CUDA; Mul at `3500 GB/s` (`90%`) for Mojo versus `3450 GB/s` (`89%`) for CUDA; Add at `3400 GB/s` (`87%`) for Mojo versus `3350 GB/s` (`86%`) for CUDA; Triad at `3450 GB/s` (`89%`) for Mojo versus `3400 GB/s` (`87%`) for CUDA; and Dot at `3050 GB/s` (`78%`) for Mojo versus `3900 GB/s` (`100%`) for CUDA. On AMD MI300A, where $B_{\mathrm{peak}} = 5300$ GB/s, the reported result is that Copy, Mul, Add, Triad, and Dot all satisfy `Mojo ≃ HIP ≃ 5250 GB/s`, or `99%` of peak [2509.21039].

The study’s interpretation is specific. For Copy, Mul, Add, and Triad, performance is dominated by global-memory throughput, and Mojo’s MLIR-generated code emits essentially the same `ld.global`/`st.global` streams as CUDA or HIP, reaching approximately `90–92%` of peak on H100 and about `100%` on MI300A. The Dot kernel behaves differently because it uses shared-memory reductions and barriers; Mojo’s reduction code is described as having a few extra instructions and slightly higher register usage than the hand-tuned vendor version, which reduces occupancy and produces the reported performance gap on H100. Table 3 further reports identical L1–L3 arithmetic intensities, matching global load/store counts, and `16` registers per thread for both Mojo and CUDA on BabelStream’s Mul and Triad; CUDA shows slightly higher “Compute SM utilization,” while memory utilization is nearly identical [2509.21039].

## 6. Limitations, caveats, and interpretation

Several constraints shape the interpretation of BabelStream results. In the AMD study, ROCProfiler provides no direct way to count L1, L2, or DRAM transactions, so instruction intensity is expressed in `inst/byte` rather than `inst/transaction`. Different implementations of BabelStream, specifically AOMP versus HIP, can yield slightly different bandwidth numbers; the reported roofline results are explicitly for the HIP build. On AMD HPC GPUs, wavefronts are `64` threads rather than NVIDIA’s `32`-thread warps, so the formulas require wavefront normalization and would need to be revisited for architectures such as some consumer RDNA cards that use `32`-wide wavefronts [2110.08221].

BabelStream’s methodological strength is therefore also its principal limitation. Because it omits PCIe overhead and does not stress shared or texture caches, it provides a clean reference for global-HBM throughput rather than a complete end-to-end performance model. This suggests that BabelStream is most informative when used as a calibration point for roofline construction or as a controlled memory-bound kernel for code-generation studies, not as a substitute for full application profiling. In that narrower role, the cited work treats it as accurate, lightweight, and repeatable for pinning down global-memory roofs and for testing whether compiler-generated GPU kernels preserve optimal global-memory access patterns [2110.08221], [2509.21039].

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