|
Orrery
A GPU-accelerated N-body gravitational simulator
|
A GPU-accelerated N-body gravitational simulator in C++20, developed and benchmarked entirely on a single Lunar Lake laptop.
This is the documentation site. It is generated from the Markdown in the repository and from the comments in the public headers, by one run of one tool, so a page here and the file it came from cannot drift apart. The source is at github.com/Protonicwave/orrery.
Orrery simulates the gravitational interaction of large numbers of point masses. It aims to be fast enough and accurate enough to be worth taking seriously on consumer laptop hardware, and it is built around three goals in this order: correctness that can be demonstrated, performance that can be quantified, and engineering that survives inspection.
It is a gravitational N-body simulator and not a framework for physics in general. General relativity, hydrodynamics, collisional stellar dynamics with regularisation and distributed multi-node execution are all outside it. Each is a reasonable extension and none is in scope, because a framework with one solver in it is a solver with extra indirection.
Everything the project claims is in one of these, and every claim in them names the test or the command that produces it.
Five decisions shape the rest of the code, and each of them is load-bearing enough that changing it would change everything above it.
Particles are stored as separate contiguous arrays rather than as an array of structs. The force kernel reads positions and masses and nothing else. Under an array-of-structs layout every cache line it fetched would also carry velocities and accelerations it never touches, wasting a large share of the bandwidth that already binds. Separate arrays also give contiguous vector loads instead of strided gathers.
Virtual dispatch sits at boundaries and never inside a loop. Solvers and backends are selected at run time, so a benchmark or a test can swap implementations from a flag. The cost is one indirect call per timestep ahead of billions of floating-point operations, and it is unmeasurable. No virtual call appears in any loop over particles.
A GPU implementation is a backend behind the solver interface, not a second copy of the solver. Two divergent implementations of the same physics is the usual way a project of this kind decays, and ADR-0026 puts the device behind the interface rather than in front of it.
Precision is selected at build time. Real is double by default and float under a build option. Templating every solver on the scalar type would multiply compile times and complicate the SYCL kernels for no practical gain, because a given run is either accuracy-oriented or throughput-oriented and never both.
The direct solver is the reference and is never deleted. Every approximation, whether an opening angle, a multipole order or a reduced precision, is measured against direct summation in double precision.