From 80a51cd8193f3ae566ad39cd57a8ceaf4f756dcc Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:30:58 +0100 Subject: [PATCH 1/2] chore: bump DI to v0.7.10 --- DifferentiationInterface/CHANGELOG.md | 51 +++++++++++++++------------ DifferentiationInterface/Project.toml | 2 +- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/DifferentiationInterface/CHANGELOG.md b/DifferentiationInterface/CHANGELOG.md index 5364547ca..09b965f79 100644 --- a/DifferentiationInterface/CHANGELOG.md +++ b/DifferentiationInterface/CHANGELOG.md @@ -5,100 +5,107 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.9...main) +## [Unreleased](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.10...main) + +## [0.7.10](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.9...DifferentiationInterface-v0.7.10) + +### Fixed + +- Add `Prep` to the public interface ([#875](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/875)) +- Improve performance of unbatched out-of-place Jacobian ([#876](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/875)) ## [0.7.9](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.8...DifferentiationInterface-v0.7.9) ### Fixed - - Handle empty row or column colors in mixed mode sparse Jacobian ([#864](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/864)) +- Handle empty row or column colors in mixed mode sparse Jacobian ([#864](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/864)) ## [0.7.8](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.7...DifferentiationInterface-v0.7.8) ### Added - - Support the new `ADTypes.NoAutoDiff` ([#851](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/851)) +- Support the new `ADTypes.NoAutoDiff` ([#851](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/851)) ### Fixed - - Speed up Mooncake by avoiding tuple broadcasting ([#853](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/853)) +- Speed up Mooncake by avoiding tuple broadcasting ([#853](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/853)) ## [0.7.7](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.6...DifferentiationInterface-v0.7.7) ### Fixed - - Improve support for empty inputs (still not guaranteed) ([#835](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/835)) +- Improve support for empty inputs (still not guaranteed) ([#835](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/835)) ## [0.7.6](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.5...DifferentiationInterface-v0.7.6) ### Fixed - - Put test deps into `test/Project.toml` ([#840](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/840)) - - Set up `pre-commit` ([#837](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/837)) +- Put test deps into `test/Project.toml` ([#840](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/840)) +- Set up `pre-commit` ([#837](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/837)) ### Fixed - - Put test deps into `test/Project.toml` ([#840](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/840)) +- Put test deps into `test/Project.toml` ([#840](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/840)) ## [0.7.5](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.4...DifferentiationInterface-v0.7.5) ### Added - - Support forward-mode Mooncake with `AutoMooncakeForward` ([#813](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/813)) +- Support forward-mode Mooncake with `AutoMooncakeForward` ([#813](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/813)) ## [0.7.4](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.3...DifferentiationInterface-v0.7.4) ### Added - - Make `AutoForwardFromPrimitive` and `AutoReverseFromPrimitive` public ([#825](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/825)) +- Make `AutoForwardFromPrimitive` and `AutoReverseFromPrimitive` public ([#825](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/825)) ### Fixed - - Replace `one` with `oneunit` in basis computation ([#826](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/826)) +- Replace `one` with `oneunit` in basis computation ([#826](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/826)) ## [0.7.3](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.2...DifferentiationInterface-v0.7.3) ### Fixed - - Bump compat for SparseConnectivityTracer v1 ([#823](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/823)) +- Bump compat for SparseConnectivityTracer v1 ([#823](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/823)) ## [0.7.2](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.1...DifferentiationInterface-v0.7.2) ### Feat - - Backend switching for Mooncake ([#768](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/768)) +- Backend switching for Mooncake ([#768](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/768)) ### Fixed - - Speed up sparse preparation for GPU arrays ([#818](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/818)) +- Speed up sparse preparation for GPU arrays ([#818](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/818)) ## [0.7.1](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.7.0...DifferentiationInterface-v0.7.1) ### Feat - - Use Mooncake's internal copy utilities ([#809](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/809)) +- Use Mooncake's internal copy utilities ([#809](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/809)) ### Fixed - - Take `absstep` into account for FiniteDiff ([#812](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/812)) - - Make basis work for `CuArray` ([#810](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/810)) +- Take `absstep` into account for FiniteDiff ([#812](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/812)) +- Make basis work for `CuArray` ([#810](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/810)) ## [0.7.0](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.6.54...DifferentiationInterface-v0.7.0) ### Changed - - Preparation is now strict by default ([#799](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/799)) - - New Arxiv preprint for citation ([#795](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/795)) +- Preparation is now strict by default ([#799](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/799)) +- New Arxiv preprint for citation ([#795](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/795)) ## [0.6.54](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.6.53...DifferentiationInterface-v0.6.54) - 2025-05-11 ### Added - - Dependency compat bounds for extras ([#790](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/790)) - - Error hints for Enzyme ([#788](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/788)) +- Dependency compat bounds for extras ([#790](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/790)) +- Error hints for Enzyme ([#788](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/788)) ## [0.6.53](https://github.com/JuliaDiff/DifferentiationInterface.jl/compare/DifferentiationInterface-v0.6.52...DifferentiationInterface-v0.6.53) - 2025-05-07 ### Changed - - Allocate Enzyme shadow memory during preparation ([#782](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/782)) +- Allocate Enzyme shadow memory during preparation ([#782](https://github.com/JuliaDiff/DifferentiationInterface.jl/pull/782)) diff --git a/DifferentiationInterface/Project.toml b/DifferentiationInterface/Project.toml index 8336f7adf..15512a82a 100644 --- a/DifferentiationInterface/Project.toml +++ b/DifferentiationInterface/Project.toml @@ -1,7 +1,7 @@ name = "DifferentiationInterface" uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" authors = ["Guillaume Dalle", "Adrian Hill"] -version = "0.7.9" +version = "0.7.10" [deps] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" From 4d8e2801bc036dee68e0ad11660de3abb2439d1f Mon Sep 17 00:00:00 2001 From: Guillaume Dalle <22795598+gdalle@users.noreply.github.com> Date: Tue, 4 Nov 2025 18:39:48 +0100 Subject: [PATCH 2/2] fix: sparse Hessians of affine functions --- .../hessian.jl | 16 +++++++++++++--- .../test/Core/SimpleFiniteDiff/test.jl | 11 ++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/DifferentiationInterface/ext/DifferentiationInterfaceSparseMatrixColoringsExt/hessian.jl b/DifferentiationInterface/ext/DifferentiationInterfaceSparseMatrixColoringsExt/hessian.jl index 495b31b10..f5d674cc4 100644 --- a/DifferentiationInterface/ext/DifferentiationInterfaceSparseMatrixColoringsExt/hessian.jl +++ b/DifferentiationInterface/ext/DifferentiationInterfaceSparseMatrixColoringsExt/hessian.jl @@ -4,6 +4,7 @@ struct SMCSparseHessianPrep{ P <: AbstractMatrix, C <: AbstractColoringResult{:symmetric, :column}, M <: AbstractMatrix{<:Number}, + Sp <: NTuple, S <: AbstractVector{<:NTuple}, R <: AbstractVector{<:NTuple}, E2 <: DI.HVPPrep, @@ -14,6 +15,7 @@ struct SMCSparseHessianPrep{ sparsity::P coloring_result::C compressed_matrix::M + batched_seed_prep::Sp batched_seeds::S batched_results::R hvp_prep::E2 @@ -54,14 +56,20 @@ function _prepare_sparse_hessian_aux( (; N, A) = batch_size_settings dense_backend = dense_ad(backend) groups = column_groups(coloring_result) + seed_prep = DI.multibasis(x, eachindex(x)) seeds = [DI.multibasis(x, eachindex(x)[group]) for group in groups] - compressed_matrix = stack(_ -> vec(similar(x)), groups; dims = 2) + compressed_matrix = if isempty(groups) + similar(x, length(x), 0) + else + stack(_ -> vec(similar(x)), groups; dims = 2) + end + batched_seed_prep = ntuple(b -> copy(seed_prep), Val(B)) batched_seeds = [ ntuple(b -> seeds[1 + ((a - 1) * B + (b - 1)) % N], Val(B)) for a in 1:A ] batched_results = [ntuple(b -> similar(x), Val(B)) for _ in batched_seeds] hvp_prep = DI.prepare_hvp_nokwarg( - strict, f, dense_backend, x, batched_seeds[1], contexts... + strict, f, dense_backend, x, batched_seed_prep, contexts... ) gradient_prep = DI.prepare_gradient_nokwarg( strict, f, DI.inner(dense_backend), x, contexts... @@ -72,6 +80,7 @@ function _prepare_sparse_hessian_aux( sparsity, coloring_result, compressed_matrix, + batched_seed_prep, batched_seeds, batched_results, hvp_prep, @@ -92,6 +101,7 @@ function DI.hessian!( batch_size_settings, coloring_result, compressed_matrix, + batched_seed_prep, batched_seeds, batched_results, hvp_prep, @@ -100,7 +110,7 @@ function DI.hessian!( dense_backend = dense_ad(backend) hvp_prep_same = DI.prepare_hvp_same_point( - f, hvp_prep, dense_backend, x, batched_seeds[1], contexts... + f, hvp_prep, dense_backend, x, batched_seed_prep, contexts... ) for a in eachindex(batched_seeds, batched_results) diff --git a/DifferentiationInterface/test/Core/SimpleFiniteDiff/test.jl b/DifferentiationInterface/test/Core/SimpleFiniteDiff/test.jl index 0d8d0f703..1bd40bfa6 100644 --- a/DifferentiationInterface/test/Core/SimpleFiniteDiff/test.jl +++ b/DifferentiationInterface/test/Core/SimpleFiniteDiff/test.jl @@ -136,7 +136,16 @@ end @test only(column_groups(hess_prep)) == 1:10 end - @testset "Empty colors for mixed mode" begin # issue 857 + @testset "Empty color groups in sparse AD" begin # issue 857 + # forward + backend = MyAutoSparse(adaptive_backends[1]) + @test jacobian(zero, backend, ones(10)) isa AbstractMatrix + @test hessian(sum ∘ zero, backend, ones(10)) isa AbstractMatrix + # reverse + backend = MyAutoSparse(adaptive_backends[2]) + @test jacobian(zero, backend, ones(10)) isa AbstractMatrix + @test hessian(sum ∘ zero, backend, ones(10)) isa AbstractMatrix + # mixed backend = MyAutoSparse(MixedMode(adaptive_backends[1], adaptive_backends[2])) @test jacobian(copyto!, zeros(10), backend, ones(10)) isa AbstractMatrix end