Conversation
Base computes some single-precision math in double precision, which fails to compile for devices without Float64 support (and is slow on devices where it is emulated or has a low throughput). This adds `GPUToolbox.Overlays`, for method tables with device overrides that back-ends can share by stacking them underneath their own method table. The module's documentation describes the lookup order and the rules the overrides follow. The first table, `Overlays.float64_overrides`, keeps these computations in single precision: - `div` and friends on Float32 (Julia 1.12 and 1.13) - `sind`, `cosd` and friends on Float32 - `sincospi`, and thus `cispi` and complex `sinpi`/`cospi` - `hypot` on Float32, and thus `abs` of complex numbers - `^(::Float32, ::Integer)` - division and inversion of ComplexF32 - comparisons between Float32/Float16 and 32-bit integers These only fix Base's generic code: back-ends still need to provide native implementations of elementary functions like `sin`. `Overlays.audit` checks a stack of tables for overrides that don't match any Base method, or that are hidden by a table higher up the stack.
This was referenced Sep 23, 2026
Member
|
Nice! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
GPU back-ends replace Base methods that don't work well on GPUs with overlay methods in their own method table, and many of these overrides are the same across back-ends. This adds
GPUToolbox.Overlays, a home for such overrides: method tables that back-ends stack underneath their own usingGPUCompiler.StackedMethodTableinGPUCompiler.method_table_view(like OpenCL.jl and oneAPI.jl already do with SPIRVIntrinsics' table). The module docstring (also a new docs page) describes the design: lookup order (back-end first, then family tables like SPIRVIntrinsics, then these tables, then Base), the rules shared overrides follow so that the order only affects speed or accuracy and not correctness, and how to use them.Overlays.float64_overridesThe first table replaces Base methods that use Float64 to compute single- and half-precision results, which fails to compile on devices without Float64 support (Metal, many Intel GPUs) and is slow where Float64 is emulated or has low throughput:
div,fld,cldand friends of Float32 values on Julia 1.12 and 1.13, using the generic implementation Base master switched to (Fix incorrect results from floating-point division (fld, cld, div) JuliaLang/julia#60497), while keeping 1.12's results for non-finite operands and zero quotients;sind,cosdand friends of Float32 values, keeping Base's argument reduction but evaluatingsin/cosin single precision;sincospi, and thuscispiand complexsinpi/cospi;hypotof Float32 values, and thusabsof complex numbers;^(::Float32, ::Integer);ComplexF32, using a port of Base's robust ComplexF64 division (Baudin & Smith) with thresholds that keep intermediate values out of the subnormal range, which GPUs may flush to zero; zero components get the same signs as Base's;These only fix Base's generic code: back-ends still provide Float64-free elementary functions like
sinthemselves, as documented. The plan is for Metal.jl to always stack this table, and for OpenCL.jl and oneAPI.jl to stack it on devices without Float64 support; those PRs follow once this is released. On Metal, it fixes JuliaGPU/Metal.jl#972, #973 and #871, and makes about 30 more Base functions compile.Overlays.auditOverlays.audit(tables...)checks a stack of method tables for overrides of Base functions that don't match any Base method (e.g. because Base changed a signature), and for overrides hidden by a table higher up the stack. GPUToolbox's tests run it on its own tables. Running it on the back-ends' tables found a dead override in every back-end (removed in JuliaGPU/Metal.jl#974, JuliaGPU/OpenCL.jl#494, JuliaGPU/KernelAbstractions.jl#789, JuliaGPU/oneAPI.jl#638, JuliaGPU/CUDA.jl#3284, JuliaGPU/AMDGPU.jl#1097).Testing
The overrides are tested on the CPU by invoking their methods directly (Julia 1.12+); calls made by an override then resolve to Base, so the composed behavior is tested in the back-ends. With Metal.jl stacking the table, its math tests pass on Julia 1.10 through 1.13, and a comparison against Base on an M1 GPU matched
divin all rounding modes (where the quotient is exact), with integer powers within 2.6 ulp, complex division within about 1.5 eps (normwise; 1.53 eps worst case on the CPU),sind/cosd/tandwithin 4 ulp andhypotwithin 1 ulp. OpenCL.jl compiles these functions without Float64 on PoCL.Bumps the version to 3.1.0.