|
Orrery
A GPU-accelerated N-body gravitational simulator
|
Finding the GPU, and reporting what was found. More...
#include <cstdint>#include <optional>#include <string>Go to the source code of this file.
Classes | |
| struct | orrery::backend::DeviceDescription |
| What the runtime reports about a device, in types that do not require SYCL. More... | |
Functions | |
| std::optional< DeviceDescription > | orrery::backend::discover_gpu_device () noexcept |
| The GPU this machine offers, or nothing. | |
| std::optional< DeviceDescription > | orrery::backend::describe_default_device () noexcept |
| Every device the runtime can see, GPU or not. | |
| std::string | orrery::backend::to_string (const DeviceDescription &device) |
| A one-line summary, for a benchmark table or a test failure message. | |
Variables | |
| constexpr bool | orrery::backend::kSyclBackendCompiled |
| Whether this build contains the SYCL backend at all. | |
Finding the GPU, and reporting what was found.
This is the only part of the SYCL backend that a caller compiled without SYCL can still ask questions of. Everything else in the backend is guarded on ORRERY_ENABLE_SYCL and simply does not exist in an ordinary build, which is the same arrangement the AVX2 kernel uses and for the same reason: the question of whether a code path was compiled is the one question C++ cannot ask about itself.
There are three distinct ways a machine can fail to run a GPU kernel, and a caller usually wants to tell them apart. The build may not include the backend at all. The build may include it while the machine has no device the runtime recognises, which is the ordinary state of a continuous integration runner. Or a device may be present but lack something the kernel needs, which on this project means double precision on a build that was not configured for single. Collapsing all three into a thrown exception at construction would make the common case, a laptop with no discrete GPU running the CPU solver, look like an error.
So discovery answers with an optional description and never throws. A caller that wants a GPU asks, and falls back to a CPU solver when the answer is empty. docs/performance/sycl_direct.md reports the description of the machine its figures were taken on, which is the same struct printed.
Section 2 of the implementation plan rests an architectural claim on this hardware having no host-to-device copy, and Phase 9's definition of done asks for that to be demonstrated rather than asserted. The four USM aspects below are the runtime's own answers about what this device can address, read rather than inferred from the fact that the part is integrated, and they are reported alongside every figure this backend produces.
The one that decides the backend's shape is supports_system_usm. A device with it can dereference memory from an ordinary new or malloc, which would let a kernel read core::ParticleData's arrays where they lie and remove the staging step in the solver entirely. The target GPU reports it false, which is why the staging step exists. ADR-0027 records the consequence, and this is the query behind it rather than an assumption about integrated parts in general.
SYCL 2020 deprecated info::device::host_unified_memory, the flag that would otherwise be the obvious thing to ask, in favour of exactly these aspects. The project's builds treat warnings as errors, so the deprecated descriptor is not queried, and nothing is lost: what it reported is what the aspects report between them, in more detail.
|
nodiscardnoexcept |
The GPU this machine offers, or nothing.
Returns empty when the backend was not compiled, when the runtime reports no device, when no device is a GPU, or when the runtime throws during discovery, which it does on a machine whose driver is installed but broken. All four are the same answer to the caller's actual question, which is whether there is a GPU to run on.
Never throws. Discovery is the one operation that has to work on a machine where nothing else does.
|
nodiscardnoexcept |
Every device the runtime can see, GPU or not.
For the diagnostic case rather than the running case: when discover_gpu_device returns nothing, this is what says whether the runtime found nothing at all or found only a CPU device, and those point at different problems. Empty when the backend was not compiled.
|
inlineconstexpr |
Whether this build contains the SYCL backend at all.
A constant rather than a function because it describes the translation unit that reads it, exactly as core::kSinglePrecision does. A test that skips its GPU cases needs the answer at compile time so that the cases it skips do not have to link against a solver that was never built.