C2 — Run one loop on the CPU or the GPU, unchanged#
The same source file compiles against CUDA and against plain C++/OpenMP – one dispatch call, two backends, no
#ifdefin the body.
Time: ~3 min · Runs on: CUDA GPU or CPU (OpenMP) – pick the build command · You need: C1 (the capture/replay vocabulary), a C++23 compiler
eagle::cpu::Host::launch runs one task per index through eagle’s OpenMP +
SIMD host launcher: consecutive indices are batched into aether SIMD packets and
spread across threads. The same source compiles and runs in CUDA mode
(02_host_dispatch.cu) and pure-C++ mode (02_host_dispatch.cpp) – that is
eagle’s dual-mode promise.
// One host task per index i; i.global() is this task's flat index. We write
// the sequence of odd numbers 1, 3, 5, ... whose prefix sums are N*N.
eagle::cpu::Host::launch(N, [&](const auto& i) {
const eagle::idx_t k = i.global();
x[k] = 2.0 * static_cast<double>(k) + 1.0;
});
What it printed#
Both builds print the same line (the prefix sums of the first N odd numbers are N2):
02_host_dispatch: N=1024 sum=1048576 (expected 1048576) : OK
What just happened#
The loop body is one line, written once;
Host::launchis what changes between the CUDA build (a device kernel over the same body) and the pure-C++ build (an OpenMP + SIMD host loop).N=1024 lanes each wrote their own prefix sum; the host and device builds agree on every element, not just the final total.
Nothing in
02_host_dispatch.cu/.cppnamesCUDAorOpenMPdirectly – the backend is a build flag (EAGLE_CPU_ONLY), not a code branch.
Try this#
Change N from 1024 to 1 and rebuild both modes: the printed sum becomes 1
either way – a batch of one is not a special case.
Next#
C3 (C3 — Reduce an array, the same way on either backend) – the same dual-mode idea applied to a reduction instead of a per-element write.