From ff025f445d42145fba17d2d17cd5805966642675 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Tue, 29 Sep 2026 17:18:36 +0200 Subject: [PATCH 1/3] Restore custom rule for twist to calm 1.10 --- ext/TensorKitEnzymeExt/indexmanipulations.jl | 51 ++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/ext/TensorKitEnzymeExt/indexmanipulations.jl b/ext/TensorKitEnzymeExt/indexmanipulations.jl index e93c06dac..873b87905 100644 --- a/ext/TensorKitEnzymeExt/indexmanipulations.jl +++ b/ext/TensorKitEnzymeExt/indexmanipulations.jl @@ -116,6 +116,57 @@ function EnzymeRules.reverse( return nothing, nothing, nothing, nothing, Δαr, Δβr, map(Returns(nothing), ba)... end +# Differentiating through the fusion tree loop corrupts the +# heap on Julia 1.10 and causes segfaults in the GC. Remove this +# custom rule when we drop support for 1.10 +function EnzymeRules.augmented_primal( + config::EnzymeRules.RevConfigWidth{1}, + func::Const{typeof(twist!)}, + ::Type{RT}, + t::Annotation{<:AbstractTensorMap}, + inds::Const; + inv::Bool = false + ) where {RT} + twist!(t.val, inds.val; inv) + primal = EnzymeRules.needs_primal(config) ? t.val : nothing + shadow = EnzymeRules.needs_shadow(config) ? t.dval : nothing + return EnzymeRules.AugmentedReturn(primal, shadow, nothing) +end + +function EnzymeRules.reverse( + config::EnzymeRules.RevConfigWidth{1}, + func::Const{typeof(twist!)}, + ::Type{RT}, + cache, + t::Annotation{<:AbstractTensorMap}, + inds::Const; + inv::Bool = false + ) where {RT} + !isa(t, Const) && twist!(t.dval, inds.val; inv = !inv) + return (nothing, nothing) +end + +function EnzymeRules.forward( + config::EnzymeRules.FwdConfigWidth{1}, + func::Const{typeof(twist!)}, + ::Type{RT}, + t::Annotation{<:AbstractTensorMap}, + inds::Const; + inv::Bool = false + ) where {RT} + twist!(t.val, inds.val; inv) + !isa(t, Const) && twist!(t.dval, inds.val; inv) + if EnzymeRules.needs_primal(config) && EnzymeRules.needs_shadow(config) + return Duplicated(t.val, t.dval) + elseif EnzymeRules.needs_primal(config) + return t.val + elseif EnzymeRules.needs_shadow(config) + return t.dval + else + return nothing + end +end + function EnzymeRules.augmented_primal( config::EnzymeRules.RevConfigWidth{1}, func::Const{typeof(flip)}, From b1ce85faadce2954be87a6d8da09ebc41baf5e80 Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Tue, 29 Sep 2026 19:51:53 +0200 Subject: [PATCH 2/3] Loosen annotation type for twist fwd rule --- ext/TensorKitEnzymeExt/indexmanipulations.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/TensorKitEnzymeExt/indexmanipulations.jl b/ext/TensorKitEnzymeExt/indexmanipulations.jl index 873b87905..0e531f286 100644 --- a/ext/TensorKitEnzymeExt/indexmanipulations.jl +++ b/ext/TensorKitEnzymeExt/indexmanipulations.jl @@ -151,7 +151,7 @@ function EnzymeRules.forward( func::Const{typeof(twist!)}, ::Type{RT}, t::Annotation{<:AbstractTensorMap}, - inds::Const; + inds::Annotation; inv::Bool = false ) where {RT} twist!(t.val, inds.val; inv) From 32e342606eac84212b4866b1106019db6ca4476d Mon Sep 17 00:00:00 2001 From: Katharine Hyatt Date: Wed, 30 Sep 2026 03:17:37 -0400 Subject: [PATCH 3/3] Bump Enzyme compat --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 83093ea5b..49cb54457 100644 --- a/Project.toml +++ b/Project.toml @@ -51,7 +51,7 @@ Adapt = "4" CUDA = "6" ChainRulesCore = "1" Dictionaries = "0.4" -Enzyme = "0.13.195" +Enzyme = "0.13.207" EnzymeTestUtils = "0.2.8" FiniteDifferences = "0.12" GPUArrays = "11.4.1"