Skip to content

Restore non-differentiable rand!(::AbstractRNG, ::AbstractArray) - #866

Merged
devmotion merged 1 commit into
mainfrom
dmw/rand-gpu-arrays
Nov 7, 2026
Merged

devmotion merged 1 commit into
mainfrom
dmw/rand-gpu-arrays

Conversation

@devmotion

Copy link
Copy Markdown
Member

Fixes #865.

Problem

#855 removed rand!(::AbstractRNG, ::AbstractArray) because for Random's RNGs it forwards to the sampler rules. GPUArrays and CUDA, however, implement rand!(rng, A) directly without a sampler, and forward all their out-of-place rand(rng, T, dims...), rand(rng, dims...) methods to it. Zygote therefore differentiates into their kernels.

Change

Restore only @non_differentiable rand!(::AbstractRNG, ::AbstractArray), the lowest-level function that all GPU paths reach. Its output depends only on eltype(A), and the previous values of A are overwritten.

Not added, compared with the proposal in #865:

  • rand(::AbstractRNG, ::Type, ...), rand(::AbstractRNG, ::Integer...): forwarders to rand! in GPUArrays and CUDA.
  • rand(::AbstractRNG, ::Dims): forwarder as well; moreover, in Base rand(rng, (5, 7)) samples from the tuple.
  • rand!(::AbstractArray): Base and CUDA forward it to the 2-arg rand!.
  • rand!(::AbstractRNG, ::AbstractArray, ::Type) would not help: GPU packages define the 2-arg method, so it is never reached.

Zygote on JLArrays (GPUArrays reference backend)

main this PR
rand!(GPUArrays.RNG{JLArray}(...), A), rand!(Xoshiro(1), A) error ✅
rand(GPUArrays.RNG{JLArray}(...), Float32, 3), same with (3,), rand(rng, 3), rand(rng, (3,)) error ✅
CPU: rand(rng, [x]), x .* rand!(rng, zeros(3)) ✅ ✅ (unchanged)

Not verified

No CUDA available. rand!(CUDA.default_rng(), A) hits the rule directly. rand!(A) and rand(CUDA.default_rng(), Float32, 3) reach it after library_rng() and CuArray{T}(undef, dims), which, judging from the errors in #865, Zygote already traces fine. @CarloLucibello, could you re-run your table on this branch?

🤖 Generated with Claude Code

GPUArrays and CUDA implement `rand!(rng, A)` directly, without a sampler,
and forward their out-of-place `rand(rng, ...)` methods to it. Since #855
removed this rule, Zygote differentiates into their kernels and errors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.65%. Comparing base (a6107e9) to head (21093c8).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #866   +/-   ##
=======================================
  Coverage   96.65%   96.65%           
=======================================
  Files          28       28           
  Lines        3614     3615    +1     
=======================================
+ Hits         3493     3494    +1     
  Misses        121      121           

☔ 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.

@devmotion
devmotion merged commit f5fa82f into main Nov 7, 2026
11 checks passed
@devmotion
devmotion deleted the dmw/rand-gpu-arrays branch November 7, 2026 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rand!(rng, A) and rand(rng, T, dims) with GPU arrays error in Zygote since 1.74.4

1 participant