|
1 | 1 | // SPDX-License-Identifier: PMPL-1.0-or-later |
2 | 2 | = AcceleratorGate.jl — Show Me The Receipts |
| 3 | +Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk> |
3 | 4 | :toc: |
| 5 | +:toclevels: 3 |
4 | 6 | :icons: font |
5 | 7 |
|
6 | | -The README makes claims. This file backs them up. |
| 8 | +The README makes claims. This file backs them up with specific code locations, |
| 9 | +honest caveats, and enough trace information for an external reviewer to navigate |
| 10 | +the codebase cold. |
7 | 11 |
|
8 | | -[quote, README] |
| 12 | +== Claim 1: Unified accelerator abstraction layer for GPU, TPU, NPU, FPGA, QPU, DSP, and more |
| 13 | + |
| 14 | +[quote, README — Overview] |
9 | 15 | ____ |
10 | | -Jonathan D. A. Jewell <j.d.a.jewell@open.ac.uk> |
| 16 | +Unified accelerator abstraction layer for Julia — GPU, TPU, NPU, FPGA, QPU, DSP, and more. |
11 | 17 | ____ |
12 | 18 |
|
13 | | -== Technology Choices |
| 19 | +*How it works:* `src/AcceleratorGate.jl` defines a flat type hierarchy rooted at the |
| 20 | +abstract type `AbstractBackend`. Every concrete accelerator family is its own struct: |
| 21 | +`CUDABackend(device::Int)`, `ROCmBackend(device::Int)`, `MetalBackend(device::Int)`, |
| 22 | +`TPUBackend`, `NPUBackend`, `DSPBackend`, `PPUBackend`, `MathBackend`, `FPGABackend`, |
| 23 | +`VPUBackend`, `QPUBackend`, and `CryptoBackend`. Two union types further group them: |
| 24 | +`GPUBackend = Union{CUDABackend, ROCmBackend, MetalBackend}` and `CoprocessorBackend` |
| 25 | +covering the remaining nine specialised units. There are also `JuliaBackend`, |
| 26 | +`RustBackend(lib_path)`, and `ZigBackend(lib_path)` for non-hardware execution paths. |
14 | 27 |
|
15 | | -[cols="1,2"] |
16 | | -|=== |
17 | | -| Technology | Learn More |
| 28 | +Backend selection is process-global via a `Ref{AbstractBackend}` thread-unsafe singleton |
| 29 | +(`_current_backend`). The `@with_backend` macro provides scoped override with restore-on-exit. |
18 | 30 |
|
19 | | -| **Julia** | https://julialang.org |
20 | | -|=== |
| 31 | +*Honest caveat:* Availability detection is entirely environment-variable-driven |
| 32 | +(`AXIOM_CUDA_AVAILABLE`, `AXIOM_ROCM_AVAILABLE`, etc.). There is no runtime |
| 33 | +probing of actual hardware. On a machine with a GPU that does not set these |
| 34 | +vars, `detect_gpu()` returns `nothing`. The module is a dispatch scaffold, not a |
| 35 | +hardware driver. |
| 36 | + |
| 37 | +== Claim 2: Platform-aware auto-detection covering mobile, embedded, server, and desktop |
| 38 | + |
| 39 | +[quote, README — Source module docstring] |
| 40 | +____ |
| 41 | +Platform-aware auto-detection (mobile, embedded, server, desktop) |
| 42 | +____ |
| 43 | + |
| 44 | +*How it works:* `detect_platform()` in `src/AcceleratorGate.jl` (line ~236) probes |
| 45 | +`Sys.islinux()`, `Sys.isapple()`, `Sys.iswindows()`, `Sys.isbsd()` and falls back to |
| 46 | +`uname -s` for MINIX and OpenBSD. Android is distinguished from Linux via the |
| 47 | +`ANDROID_ROOT` environment variable and `/system/app` path presence. iOS is |
| 48 | +distinguished from macOS by the heuristic `aarch64 + no /usr/local`. Embedded |
| 49 | +environments are flagged at `CPU_THREADS <= 2 AND total_memory < 512 MiB`; server |
| 50 | +environments at `CPU_THREADS >= 16 OR total_memory > 32 GiB`. Architecture |
| 51 | +compatibility is enforced in `_arch_compatible/2` — for example, `MetalBackend` |
| 52 | +is only considered compatible with `:aarch64`. |
| 53 | + |
| 54 | +`select_backend` uses this platform information together with `DeviceCapabilities` |
| 55 | +structs and cost estimates to choose the cheapest suitable backend for an operation. |
| 56 | + |
| 57 | +*Honest caveat:* The iOS heuristic (`aarch64 + no /usr/local`) is fragile — Apple |
| 58 | +Silicon Macs running in unusual configurations may be misidentified. The server |
| 59 | +heuristic fires on any machine with 16+ threads, including developer workstations. |
| 60 | + |
| 61 | +== How It Is Checked |
| 62 | + |
| 63 | +Tests live in `test/runtests.jl`. Coverage includes: |
| 64 | + |
| 65 | +- All 15 backend struct constructors satisfy `isa AbstractBackend` |
| 66 | +- Union membership (`CUDABackend isa GPUBackend`, `TPUBackend isa CoprocessorBackend`) |
| 67 | +- `@with_backend` scoping restores original backend after block exit |
| 68 | +- Detection returns `false`/`0`/`nothing` without env vars set |
| 69 | +- Detection returns correct types when env vars are set (`withenv(...)`) |
| 70 | +- `capability_report()` produces a dict with `generated_at`, `strategy_order`, |
| 71 | + `backends`, `platform`, and `selected_backend` keys |
| 72 | +- `runtime_diagnostics()` accumulates and resets fallback counters correctly |
| 73 | +- `_coprocessor_label`, `_coprocessor_key`, `_coprocessor_required_env` helpers |
21 | 74 |
|
22 | 75 | == File Map |
23 | 76 |
|
24 | | -[cols="1,2"] |
| 77 | +[cols="2,4"] |
25 | 78 | |=== |
26 | 79 | | Path | What's There |
27 | 80 |
|
28 | | -| `src/` | Source code |
29 | | -| `test(s)/` | Test suite |
| 81 | +| `src/AcceleratorGate.jl` |
| 82 | +| Entire module — backend type hierarchy, env-var detection, `@with_backend` macro, |
| 83 | + platform probing (`PlatformInfo`, `detect_platform`), `DeviceCapabilities`, `select_backend`, |
| 84 | + memory tracking, operation registry, self-healing hook generator, capability report. |
| 85 | + ~600 lines, single file. |
| 86 | + |
| 87 | +| `test/runtests.jl` |
| 88 | +| Full test suite. Uses `withenv(...)` to exercise detection logic without real hardware. |
| 89 | + Covers types, unions, scoped dispatch, diagnostics, resource-aware selection, and |
| 90 | + `generate_self_healing_hooks`. |
| 91 | + |
| 92 | +| `Project.toml` |
| 93 | +| Package identity (`uuid`, `name = "AcceleratorGate"`), Julia version compat, |
| 94 | + and test dependencies (`Test`). MPL-2.0 fallback declared here for ecosystem |
| 95 | + compatibility. |
| 96 | + |
| 97 | +| `LICENSE` / `LICENSES/` |
| 98 | +| PMPL-1.0-or-later full text; MPL-2.0 fallback text for Julia registry. |
| 99 | +|=== |
| 100 | + |
| 101 | +== Dogfooded Across The Account |
| 102 | + |
| 103 | +[cols="2,4"] |
| 104 | +|=== |
| 105 | +| Repo | How AcceleratorGate (or this domain) appears |
| 106 | + |
| 107 | +| `Hyperpolymath.jl` |
| 108 | +| Listed as one of the six "Metal Layer" packages pulled in by the umbrella metapackage |
| 109 | + (`using AcceleratorGate` in `src/Hyperpolymath.jl`). |
| 110 | + |
| 111 | +| `HackenbushGames.jl` |
| 112 | +| Includes `src/backends/abstract.jl` and calls `current_backend()` / `backend_move_gen` |
| 113 | + in `moves/2` for coprocessor-offloaded move generation over large edge sets. |
| 114 | + |
| 115 | +| `LowLevel.jl` |
| 116 | +| Sibling Metal Layer package; coordinates with `SiliconCore` and `HardwareResilience` |
| 117 | + for the execution layer that `AcceleratorGate` dispatches into. |
| 118 | + |
| 119 | +| `developer-ecosystem/julia-ecosystem/` |
| 120 | +| Julia ecosystem monorepo where all standalone `.jl` packages are also tracked as |
| 121 | + subdir packages; accelerator dispatch patterns are referenced in Axiom.jl backend docs. |
| 122 | + |
| 123 | +| `statistease` |
| 124 | +| Uses Julia batch scripts for statistical processing; the accelerator abstraction |
| 125 | + pattern established here informs backend selection in compute-heavy Julia scripts. |
30 | 126 | |=== |
31 | 127 |
|
32 | 128 | == Questions? |
|
0 commit comments