Skip to content

Use GPUToolbox's Float64-free overrides of Base math - #975

Merged
maleadt merged 1 commit into
mainfrom
tb/gputoolbox-math
Sep 23, 2026
Merged

maleadt merged 1 commit into
mainfrom
tb/gputoolbox-math

Conversation

@maleadt

@maleadt maleadt commented Sep 23, 2026

Copy link
Copy Markdown
Member

Several Base methods compute single-precision results in double precision, which Metal doesn't support, so they failed to compile. This stacks GPUToolbox.Overlays.float64_overrides (JuliaGPU/GPUToolbox.jl#21, GPUToolbox 3.1) underneath Metal's method table, which replaces them with Float64-free implementations:

Metal's own overrides of complex division, integer powers and hypot are removed in favor of GPUToolbox's, which changes some results:

  • complex division uses a port of Base's robust ComplexF64 algorithm (Baudin & Smith): within about 1.5 eps (normwise) over the whole range, no longer loses a normal-sized component when intermediate ratios underflow, and gives zeros the same signs as Base (e.g. (1+0im)/(-1-0im) is now -1+0im, so log of it has imaginary part +π like on the CPU);
  • Base's own _cpow is used for complex powers again, instead of exp(p * log(z)), which is more accurate for integer exponents and matches the CPU;
  • hypot uses Base's generic implementation, within 1 ulp.

Tests: a new testset covering the fixed functions, plus complex inv///atan/powers. The math tests pass locally on Julia 1.10 through 1.13 (M1, macOS 27), and a comparison against CPU Base on the GPU matched div in all rounding modes where the quotient is exact. Complex sinpi on Julia 1.13 additionally needs JuliaGPU/GPUCompiler.jl#936, so it's left out of the tests until that is released.

Stack GPUToolbox.Overlays.float64_overrides underneath Metal's method
table, which keeps Base's single-precision math that is computed in
Float64 from failing to compile. This fixes `div`, `fld` and `cld` on
Julia 1.12+ (#972), `sind` and friends (#973), `inv` of ComplexF32
(#871), as well as `sincospi`, `cispi` and comparisons of Float32
with Int32 values.

The complex division, integer power and `hypot` overrides are now
provided by GPUToolbox. Base's own `_cpow` works again as well, which
is more accurate for integer exponents than `exp(p * log(z))`.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metal Benchmarks

Details
Benchmark suite Current: 80327a2 Previous: 5210727 Ratio
array/accumulate/Float32/1d 391250 ns 390042 ns 1.00
array/accumulate/Float32/dims=1 363500 ns 367625 ns 0.99
array/accumulate/Float32/dims=1L 8768791 ns 8770083 ns 1.00
array/accumulate/Float32/dims=2 429875 ns 430042 ns 1.00
array/accumulate/Float32/dims=2L 2516041 ns 2030542 ns 1.24
array/accumulate/Int64/1d 806125 ns 813375 ns 0.99
array/accumulate/Int64/dims=1 904083 ns 901958 ns 1.00
array/accumulate/Int64/dims=1L 9451083 ns 9454916 ns 1.00
array/accumulate/Int64/dims=2 1210458 ns 1203041 ns 1.01
array/accumulate/Int64/dims=2L 6432583 ns 6431458 ns 1.00
array/broadcast 236541 ns 242542 ns 0.98
array/construct 2292 ns 2291 ns 1.00
array/permutedims/2d 436042 ns 384834 ns 1.13
array/permutedims/3d 999583 ns 999750 ns 1.00
array/permutedims/4d 1105791 ns 1083792 ns 1.02
array/private/copy 225834 ns 227459 ns 0.99
array/private/copyto!/cpu_to_gpu 214292 ns 213417 ns 1.00
array/private/copyto!/gpu_to_cpu 210791 ns 218875 ns 0.96
array/private/copyto!/gpu_to_gpu 221875 ns 220791 ns 1.00
array/private/iteration/findall/bool 1031708 ns 1034708 ns 1.00
array/private/iteration/findall/int 1208250 ns 1196167 ns 1.01
array/private/iteration/findfirst/bool 1143500 ns 1154250 ns 0.99
array/private/iteration/findfirst/int 1157292 ns 1153333 ns 1.00
array/private/iteration/findmin/1d 1206125 ns 1207917 ns 1.00
array/private/iteration/findmin/2d 1026250 ns 1038167 ns 0.99
array/private/iteration/logical 1630416 ns 1622125 ns 1.01
array/private/iteration/scalar 1378750 ns 1382000 ns 1.00
array/random/rand/Float32 418750 ns 421125 ns 0.99
array/random/rand/Int64 497333 ns 495250 ns 1.00
array/random/rand!/Float32 400250 ns 385667 ns 1.04
array/random/rand!/Int64 428625 ns 428750 ns 1.00
array/random/randn/Float32 389458 ns 388750 ns 1.00
array/random/randn!/Float32 375416 ns 373417 ns 1.01
array/reductions/mapreduce/Float32/1d 452333 ns 452125 ns 1.00
array/reductions/mapreduce/Float32/dims=1 354500 ns 355000 ns 1.00
array/reductions/mapreduce/Float32/dims=1L 609750 ns 618750 ns 0.99
array/reductions/mapreduce/Float32/dims=2 358000 ns 357709 ns 1.00
array/reductions/mapreduce/Float32/dims=2L 1239167 ns 1239666 ns 1.00
array/reductions/mapreduce/Int64/1d 640250 ns 636833 ns 1.01
array/reductions/mapreduce/Int64/dims=1 637291 ns 635709 ns 1.00
array/reductions/mapreduce/Int64/dims=1L 1013541 ns 1011542 ns 1.00
array/reductions/mapreduce/Int64/dims=2 790708 ns 792958 ns 1.00
array/reductions/mapreduce/Int64/dims=2L 2202875 ns 2208542 ns 1.00
array/reductions/reduce/Float32/1d 454792 ns 439791 ns 1.03
array/reductions/reduce/Float32/dims=1 358750 ns 358625 ns 1.00
array/reductions/reduce/Float32/dims=1L 619333 ns 613167 ns 1.01
array/reductions/reduce/Float32/dims=2 252500 ns 246125 ns 1.03
array/reductions/reduce/Float32/dims=2L 483583 ns 463833 ns 1.04
array/reductions/reduce/Int64/1d 635875 ns 634834 ns 1.00
array/reductions/reduce/Int64/dims=1 639750 ns 643459 ns 0.99
array/reductions/reduce/Int64/dims=1L 1006041 ns 1007708 ns 1.00
array/reductions/reduce/Int64/dims=2 254292 ns 253084 ns 1.00
array/reductions/reduce/Int64/dims=2L 671459 ns 667000 ns 1.01
array/shared/copy 128542 ns 128500 ns 1.00
array/shared/copyto!/cpu_to_gpu 37709 ns 37041 ns 1.02
array/shared/copyto!/gpu_to_cpu 37750 ns 37000 ns 1.02
array/shared/copyto!/gpu_to_gpu 38000 ns 37292 ns 1.02
array/shared/iteration/findall/bool 1030375 ns 1047000 ns 0.98
array/shared/iteration/findall/int 1206916 ns 1210750 ns 1.00
array/shared/iteration/findfirst/bool 973417 ns 968167 ns 1.01
array/shared/iteration/findfirst/int 979167 ns 981625 ns 1.00
array/shared/iteration/findmin/1d 1059708 ns 1066459 ns 0.99
array/shared/iteration/findmin/2d 1033666 ns 1027417 ns 1.01
array/shared/iteration/logical 1497334 ns 1500959 ns 1.00
array/shared/iteration/scalar 3921.875 ns 3729.25 ns 1.05
array/sorting/1d 2110708 ns 2066458 ns 1.02
array/sorting/2d 8345709 ns 8333292 ns 1.00
integration/byval/reference 1127458 ns 1120708 ns 1.01
integration/byval/slices=1 1123167 ns 1124667 ns 1.00
integration/byval/slices=2 2030375 ns 2032125 ns 1.00
integration/byval/slices=3 6621250 ns 6635000 ns 1.00
integration/metaldevrt 391625 ns 313542 ns 1.25
kernel/indexing 212375 ns 208417 ns 1.02
kernel/indexing_checked 396708 ns 393375 ns 1.01
kernel/launch 1829.1 ns 1762.5 ns 1.04
kernel/rand 406709 ns 401792 ns 1.01
latency/import 1786069250 ns 1780944041 ns 1.00
latency/precompile 32498069583 ns 26127754584 ns 1.24
latency/ttfp 2267194792 ns 2275447584 ns 1.00
metal/synchronization/context 556.5935828877006 ns 578.7292817679559 ns 0.96
metal/synchronization/stream 357.4766355140187 ns 347.47906976744184 ns 1.03

This comment was automatically generated by workflow using github-action-benchmark.

@codecov

codecov Bot commented Sep 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.53%. Comparing base (5210727) to head (80327a2).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #975      +/-   ##
==========================================
- Coverage   86.80%   86.53%   -0.28%     
==========================================
  Files          77       77              
  Lines        5481     5482       +1     
==========================================
- Hits         4758     4744      -14     
- Misses        723      738      +15     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@maleadt
maleadt merged commit 26c9e7d into main Sep 23, 2026
19 checks passed
@maleadt
maleadt deleted the tb/gputoolbox-math branch September 23, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant