Repository navigation
Use GPUToolbox's Float64-free overrides of Base math - #975
Merged
Merged
Conversation
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))`.
Contributor
There was a problem hiding this comment.
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 Report✅ All modified and coverable lines are covered by tests. 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. 🚀 New features to boost your workflow:
|
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.
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:div,fld,cldand friends of Float32 values on Julia 1.12 and 1.13 (fixesdiv(::Float32, ::Float32)uses Float64 on Julia ≥ 1.12 #972);sind,cosdand friends (fixessind/cosd/tandon Float32 use Float64 #973);invand division ofComplexF32(fixes Inversion ofComplexF32numbers usesFloat64numbers and fails to compile #871);sincospi, and thuscispiand complexsinpi/cospi;^(::Float32, ::Integer)andhypot.Metal's own overrides of complex division, integer powers and
hypotare removed in favor of GPUToolbox's, which changes some results:(1+0im)/(-1-0im)is now-1+0im, sologof it has imaginary part +π like on the CPU);_cpowis used for complex powers again, instead ofexp(p * log(z)), which is more accurate for integer exponents and matches the CPU;hypotuses 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 matcheddivin all rounding modes where the quotient is exact. Complexsinpion Julia 1.13 additionally needs JuliaGPU/GPUCompiler.jl#936, so it's left out of the tests until that is released.