Skip to content

Add recursivecopyto! with copyto!-style semantics#591

Merged
ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:add-recursivecopyto
May 17, 2026
Merged

Add recursivecopyto! with copyto!-style semantics#591
ChrisRackauckas merged 1 commit into
SciML:masterfrom
ChrisRackauckas-Claude:add-recursivecopyto

Conversation

@ChrisRackauckas-Claude
Copy link
Copy Markdown
Contributor

Note

Please ignore this PR until reviewed by @ChrisRackauckas.

Summary

Adds recursivecopyto! as the copyto!-style sibling of recursivecopy!. Closes the gap raised in #589.

The distinction follows Base Julia exactly:

Base This package Shape semantics
copy! recursivecopy! requires matching ndims/axes
copyto! recursivecopyto! linear-index, only requires length(b) >= length(a)

recursivecopy!'s signature (::AbstractArray{T,N}, ::AbstractArray{T2,N}) already enforces matching ndims via dispatch, matching its copy! namesake's contract. That's intentional and is preserved here — relaxing it would silently change recursivecopy! to copyto! semantics. Instead, this PR introduces a parallel recursivecopyto! for callers that want the looser linear-fill behavior (e.g. reinit(prob; u0 = some_vec) where prob.u0::Matrix).

Changes

  • src/utils.jl: new recursivecopyto! methods covering AbstractArray (delegates to copyto!), StaticArray element type, nested AbstractArray/AbstractVectorOfArray, and AbstractVectorOfArray containers. Mirrors the body of recursivecopy! but drops the N-matching constraint and uses zip(eachindex(b), eachindex(a)) so different shapes are valid.
  • src/array_partition.jl: recursivecopyto!(::ArrayPartition, ::ArrayPartition) and the VectorOfArray-of-partitions variant.
  • src/RecursiveArrayTools.jl: export.
  • docs/src/recursive_array_functions.md: docs entry.
  • test/utils_test.jl: new @testset "recursivecopyto!" covering same-shape (parity with copyto!), Matrix ← Vector (the Why doesn't recursivecopy! allow to copy a vector into a matrix? #589 case), Vector ← Matrix, different-shape same-length matrices, dst-longer / dst-shorter, nested deep-copy semantics, leaf shape mismatches, StaticArray leaves, ArrayPartition, and VectorOfArray. Also asserts the existing recursivecopy! still throws MethodError on shape mismatch.

Test plan

  • recursivecopyto! testset passes (15 assertions, run locally)
  • Existing recursivecopy! testset passes unchanged (9 assertions covering MVector/SVector/nested VoA, run locally as regression check)
  • Runic formatter applied
  • CI on SciML/RecursiveArrayTools.jl

`recursivecopy!` requires `ndims(b) == ndims(a)` via dispatch, matching
its `copy!` namesake — which errors on mismatched axes. `recursivecopyto!`
is the `copyto!` counterpart: linear-index copy with no shape check,
only requiring `length(b) >= length(a)`. This unblocks the
`reinit(prob; u0 = vec)` use case from SciML#589
without weakening `recursivecopy!`'s contract.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
@ChrisRackauckas ChrisRackauckas marked this pull request as ready for review May 17, 2026 21:49
@ChrisRackauckas-Claude
Copy link
Copy Markdown
Contributor Author

CI status (partial — 6 SciMLSensitivity / 1 RaggedArrays jobs still running):

My added paths all pass (Core, ArrayPartitionAnyAll, RaggedArrays, ShorthandConstructors, nopre, all Julia versions; GPU; Documentation; SciMLBase/OrdinaryDiffEq/DelayDiffEq/DiffEqBase/DiffEqSensitivity/LabelledArrays integration; SciMLSensitivity Core4).

4 pre-existing master failures reproduce here, none caused by this PR:

  • runic: format-only nits in test/mooncake.jl and test/named_array_partition_tests.jl (multi-line @test continuation indent + alignment spaces). Master FormatCheck has been red for the last 6 runs.
  • Tests - Downstream - Julia 1/lts/pre: test/downstream/Project.toml pins OrdinaryDiffEq = "6.31.0 - 6" but RAT 4.3.0 requires OrdinaryDiffEq v7. Master Tests has been red on these three jobs for the last several pushes.

Both being addressed in separate PRs so this one stays focused on recursivecopyto!.

@ChrisRackauckas-Claude
Copy link
Copy Markdown
Contributor Author

Update: 30/37 jobs pass (Core1/Core5 SciMLSensitivity and RaggedArrays-lts still running).

SciMLSensitivity.jl/Core6/1 also failed — verified pre-existing on master (5/11 master IntegrationTest also fails Core6 in the same downstream/test/steady_state.jl "Steady State Adjoint" testset; numerical sensitivity assertion 0.5 ≈ 0.0). Not from this PR.

Total pre-existing master failures reproducing on this branch: runic + Downstream ×3 + SciMLSensitivity Core6. All are SciMLSensitivity/dependency/CI hygiene issues unrelated to recursivecopyto!.

@ChrisRackauckas ChrisRackauckas merged commit af4895e into SciML:master May 17, 2026
31 of 37 checks passed
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.

2 participants