From 938327384daec7fb982e3459f5d221008e569e35 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 8 Jul 2026 09:46:40 -0400 Subject: [PATCH] Support DiffCache for nonzeroable element types Co-Authored-By: Chris Rackauckas --- src/PreallocationTools.jl | 6 +++++- test/core_dispatch.jl | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/PreallocationTools.jl b/src/PreallocationTools.jl index 9049567..087a998 100644 --- a/src/PreallocationTools.jl +++ b/src/PreallocationTools.jl @@ -88,12 +88,16 @@ end function DiffCache(u::AbstractArray{T}, siz, chunk_sizes; warn_on_resize::Bool = true) where {T} x = adapt( ArrayInterface.parameterless_type(u), - zeros(T, prod(chunk_sizes .+ 1) * prod(siz)) + _zeroed_or_uninitialized(T, prod(chunk_sizes .+ 1) * prod(siz)) ) xany = Any[] return DiffCache(u, x, xany, warn_on_resize) end +function _zeroed_or_uninitialized(::Type{T}, dims...) where {T} + return hasmethod(zero, Tuple{Type{T}}) ? zeros(T, dims...) : Array{T}(undef, dims...) +end + """ `DiffCache(u::AbstractArray, N::Int = forwarddiff_compat_chunk_size(length(u)); levels::Int = 1, warn_on_resize::Bool = true)` `DiffCache(u::AbstractArray; N::AbstractArray{<:Int}, warn_on_resize::Bool = true)` diff --git a/test/core_dispatch.jl b/test/core_dispatch.jl index ce8528b..bcc1832 100644 --- a/test/core_dispatch.jl +++ b/test/core_dispatch.jl @@ -33,6 +33,22 @@ end Base.zero(::Type{IsbitsPair{T}}) where {T} = IsbitsPair(zero(T), zero(T)) +@testset "DiffCache accepts isbits elements without zero" begin + u = [(; a = 1.0, b = (2.0, 3.0)), (; a = 4.0, b = (5.0, 6.0))] + cache = DiffCache(u, 3) + DualT = ForwardDiff.Dual{Nothing, Float64, 3} + tmp = get_tmp(cache, DualT) + expected_eltype = NamedTuple{(:a, :b), Tuple{DualT, Tuple{DualT, DualT}}} + + @test eltype(cache.dual_du) == eltype(u) + @test length(cache.dual_du) == 8 + @test size(tmp) == size(u) + @test eltype(tmp) == expected_eltype + + tmp[1] = (; a = zero(DualT), b = (zero(DualT), zero(DualT))) + @test tmp[1] == (; a = zero(DualT), b = (zero(DualT), zero(DualT))) +end + #Setup Base Array tests chunk_size = 5 u0 = ones(5, 5)