From 6c1d2a3c6ad1201d7c3e90820aa4e05337908f0a Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sat, 3 Oct 2026 08:18:07 -0400 Subject: [PATCH 1/3] Fix Difference hash seed widening on 32-bit (UInt == UInt32) Base.hash(::Difference, ::UInt) xored the native-width seed `u` against a bare literal (0x055640d6d952f101), which only fits UInt64. On 32-bit builds, where UInt == UInt32, this silently widens the xor result to UInt64, so the subsequent hash(D.t, ::UInt64) call on the SymbolicUtils term has no matching method (SymbolicUtils's hashconsing expects the platform's native UInt). Reducing the literal with `% UInt` keeps the result in the caller's native width on every platform. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Sonnet 5.5 Agent-Harness: Claude Code Agent-Model: claude-sonnet-5-5 Agent-Session: subagent of the qa-hygiene head session on amdci2 --- src/difference.jl | 2 +- test/Core/implicit_basis.jl | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/difference.jl b/src/difference.jl index 4c5ee160..1d741afc 100644 --- a/src/difference.jl +++ b/src/difference.jl @@ -38,4 +38,4 @@ Base.nameof(::Difference) = :Difference function Base.:(==)(D1::Difference, D2::Difference) return isequal(D1.t, D2.t) && isequal(D1.dt, D2.dt) && isequal(D1.update, D2.update) end -Base.hash(D::Difference, u::UInt) = hash(D.dt, hash(D.t, xor(u, 0x055640d6d952f101))) +Base.hash(D::Difference, u::UInt) = hash(D.dt, hash(D.t, xor(u, 0x055640d6d952f101 % UInt))) diff --git a/test/Core/implicit_basis.jl b/test/Core/implicit_basis.jl index 09c301b0..720fd6f8 100644 --- a/test/Core/implicit_basis.jl +++ b/test/Core/implicit_basis.jl @@ -56,6 +56,10 @@ end discrete_prob = DiscreteDataDrivenProblem(x) d = Difference(get_iv(basis), dt = 1.0) + # On 32-bit builds (UInt == UInt32) the hash seed literal in Base.hash(::Difference, ::UInt) + # used to widen to UInt64 via `xor`, breaking SymbolicUtils hashconsing + # (https://github.com/SciML/DataDrivenDiffEq.jl/actions/runs/35188714123). + @test typeof(hash(d, UInt(1))) === UInt @test Symbolics.symtype(d(first(states(basis)))) === Real @test isempty(Symbolics.shape(d(first(states(basis))))) ∂ = Differential(get_iv(basis)) From 1c1405e913dd88c016149f76ee2e6b2f26bf5f13 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 7 Oct 2026 10:28:15 -0400 Subject: [PATCH 2/3] Fix optimal_svht to accept Integer (Int32 on 32-bit) size(...) returns Int, which is Int32 on 32-bit Julia. optimal_svht was only defined for Int64, so Optimal Shrinkage in test/Core/utils.jl threw MethodError on the x86 Core lane after the Difference hash fix landed. Widen the signature to Integer so both architectures dispatch. Co-Authored-By: Chris Rackauckas Co-Authored-By: Cursor Agent Agent-Harness: Cursor Agent CLI Agent-Model: auto Agent-Session: ~/sandbox/goals/ci-green/work/cig-x86/log.txt (local transcript, amdci2) --- src/utils/utils.jl | 2 +- test/Core/utils.jl | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/utils.jl b/src/utils/utils.jl index 10a68440..52d898ec 100644 --- a/src/utils/utils.jl +++ b/src/utils/utils.jl @@ -3,7 +3,7 @@ # Values is 4/sqrt(3)", http://arxiv.org/abs/1305.5870 # Code taken from https://github.com/erichson/optht -function optimal_svht(m::Int64, n::Int64; known_noise::Bool = false) +function optimal_svht(m::Integer, n::Integer; known_noise::Bool = false) @assert m / n > 0 @assert m / n <= 1 diff --git a/test/Core/utils.jl b/test/Core/utils.jl index b22600f8..9cf0808e 100644 --- a/test/Core/utils.jl +++ b/test/Core/utils.jl @@ -18,6 +18,8 @@ using LinearAlgebra end @testset "Optimal Shrinkage" begin + # size(...) returns Int (== Int32 on 32-bit); optimal_svht must accept Integer + @test DataDrivenDiffEq.optimal_svht(Int(10), Int(20)) isa Real t = collect(-2:0.01:2) U = [cos.(t) .* exp.(-t .^ 2) sin.(2 * t)] S = Diagonal([2.0; 3.0]) From ea74885fad92da9c6525354a82baeb0d4dfd511e Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 7 Oct 2026 13:16:56 -0400 Subject: [PATCH 3/3] Make optimal_svht Int32 regression discriminate on 64-bit Call optimal_svht with Int32 arguments so unfixed Int64-only code fails on every platform, and rewrite the new test comments as invariants (no CI links or history narration). Co-Authored-By: Chris Rackauckas Co-Authored-By: Cursor Agent Agent-Harness: Cursor Agent CLI Agent-Model: auto Agent-Session: ~/sandbox/goals/ci-green/work/cig-x86/log.txt (local transcript, amdci2) --- test/Core/implicit_basis.jl | 4 +--- test/Core/utils.jl | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/test/Core/implicit_basis.jl b/test/Core/implicit_basis.jl index 720fd6f8..64911a2a 100644 --- a/test/Core/implicit_basis.jl +++ b/test/Core/implicit_basis.jl @@ -56,9 +56,7 @@ end discrete_prob = DiscreteDataDrivenProblem(x) d = Difference(get_iv(basis), dt = 1.0) - # On 32-bit builds (UInt == UInt32) the hash seed literal in Base.hash(::Difference, ::UInt) - # used to widen to UInt64 via `xor`, breaking SymbolicUtils hashconsing - # (https://github.com/SciML/DataDrivenDiffEq.jl/actions/runs/35188714123). + # hash(::Difference, ::UInt) must return the platform native UInt. @test typeof(hash(d, UInt(1))) === UInt @test Symbolics.symtype(d(first(states(basis)))) === Real @test isempty(Symbolics.shape(d(first(states(basis))))) diff --git a/test/Core/utils.jl b/test/Core/utils.jl index 9cf0808e..b6b81c11 100644 --- a/test/Core/utils.jl +++ b/test/Core/utils.jl @@ -18,8 +18,8 @@ using LinearAlgebra end @testset "Optimal Shrinkage" begin - # size(...) returns Int (== Int32 on 32-bit); optimal_svht must accept Integer - @test DataDrivenDiffEq.optimal_svht(Int(10), Int(20)) isa Real + # Callers pass size(...) extents; Int32 must be accepted on every platform. + @test DataDrivenDiffEq.optimal_svht(Int32(10), Int32(20)) isa Real t = collect(-2:0.01:2) U = [cos.(t) .* exp.(-t .^ 2) sin.(2 * t)] S = Diagonal([2.0; 3.0])