Skip to content

LinearAlgebra.Symmetric with \ fails but cholesky works #2967

@kylebeggs

Description

@kylebeggs

MWE:

function f(b)
    A = Symmetric([4.0 1.0; 1.0 3.0])
    return sum(A \ b)
end

b = [1.0, 2.0]
db = similar(b)
Enzyme.autodiff(Enzyme.Reverse, f, Enzyme.Active, Enzyme.Duplicated(b, db))

with environment as such:

(jl_iD8Oz3) pkg> st
Status `/tmp/jl_iD8Oz3/Project.toml`
  [7da242da] Enzyme v0.13.129
  [37e2e46d] LinearAlgebra v1.11.0

julia> versioninfo()
Julia Version 1.11.8
Commit cf1da5e20e3 (2025-11-06 17:49 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 24 × AMD Ryzen 9 9900X 12-Core Processor
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, generic)
Threads: 20 default, 0 interactive, 10 GC (on 24 virtual cores)
Environment:
  JULIA_NUM_THREADS = 20
  JULIA_PKG_USE_CLI_GIT = true

which gives the error:

ERROR: IllegalTypeAnalysisException: Enzyme compilation failed due to illegal type analysis.
 This usually indicates the use of a Union type, which is not fully supported with Enzyme.API.strictAliasing set to true [the default].
 Ideally, remove the union (which will also make your code faster), or try setting Enzyme.API.strictAliasing!(false) before any autodiff call.
 To toggle more information for debugging (needed for bug reports), set Enzyme.Compiler.VERBOSE_ERRORS[] = true (default false)
 Failure within method: MethodInstance for LinearAlgebra.var"#_factorize#135"(::Bool, ::typeof(LinearAlgebra._factorize), ::Symmetric{Float64, Matrix{Float64}})
Hint: catch this exception as `err` and call `code_typed(err)` to inspect the errornous code.
If you have Cthulu.jl loaded you can also use `code_typed(err; interactive = true)` to interactively introspect the code.
Caused by:
Stacktrace:
 [1] #_factorize#135
   @ ~/.julia/juliaup/julia-1.11.8+0.x64.linux.gnu/share/julia/stdlib/v1.11/LinearAlgebra/src/symmetric.jl:589

Stacktrace:
  [1] julia_error(msg::String, val::Ptr{LLVM.API.LLVMOpaqueValue}, errtype::Enzyme.API.ErrorType, data::Ptr{Nothing}, data2::Ptr{LLVM.API.LLVMOpaqueValue}, B::Ptr{LLVM.API.LLVMOpaqueBuilder})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/S3nC6/src/errors.jl:1167
  [2] julia_error(cstr::Cstring, val::Ptr{LLVM.API.LLVMOpaqueValue}, errtype::Enzyme.API.ErrorType, data::Ptr{Nothing}, data2::Ptr{LLVM.API.LLVMOpaqueValue}, B::Ptr{LLVM.API.LLVMOpaqueBuilder})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/S3nC6/src/errors.jl:997
  [3] EnzymeCreatePrimalAndGradient(logic::Enzyme.Logic, todiff::LLVM.Function, retType::Enzyme.API.CDIFFE_TYPE, constant_args::Vector{…}, TA::Enzyme.TypeAnalysis, returnValue::Bool, dretUsed::Bool, mode::Enzyme.API.CDerivativeMode, runtimeActivity::Bool, strongZero::Bool, width::Int64, additionalArg::Ptr{…}, forceAnonymousTape::Bool, typeInfo::Enzyme.FnTypeInfo, uncacheable_args::Vector{…}, augmented::Ptr{…}, atomicAdd::Bool)
    @ Enzyme.API ~/.julia/packages/Enzyme/S3nC6/src/api.jl:270
  [4] macro expansion
    @ ~/.julia/packages/Enzyme/S3nC6/src/compiler.jl:2772 [inlined]
  [5] macro expansion
    @ ~/.julia/packages/LLVM/fEIbx/src/base.jl:97 [inlined]
  [6] enzyme!(job::GPUCompiler.CompilerJob{…}, interp::Enzyme.Compiler.Interpreter.EnzymeInterpreter{…}, mod::LLVM.Module, primalf::LLVM.Function, TT::Type, mode::Enzyme.API.CDerivativeMode, width::Int64, parallel::Bool, actualRetType::Type, wrap::Bool, modifiedBetween::NTuple{…} where N, returnPrimal::Bool, expectedTapeType::Type, loweredArgs::Set{…}, boxedArgs::Set{…}, removedRoots::Set{…})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/S3nC6/src/compiler.jl:2645
  [7] compile_unhooked(output::Symbol, job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget{GPUCompiler.NativeCompilerTarget}, Enzyme.Compiler.EnzymeCompilerParams{Enzyme.Compiler.PrimalCompilerParams}})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/S3nC6/src/compiler.jl:5832
  [8] compile(target::Symbol, job::GPUCompiler.CompilerJob; kwargs::@Kwargs{})
    @ GPUCompiler ~/.julia/packages/GPUCompiler/OCZFZ/src/driver.jl:67
  [9] compile
    @ ~/.julia/packages/GPUCompiler/OCZFZ/src/driver.jl:55 [inlined]
 [10] _thunk(job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget{GPUCompiler.NativeCompilerTarget}, Enzyme.Compiler.EnzymeCompilerParams{Enzyme.Compiler.PrimalCompilerParams}}, postopt::Bool)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/S3nC6/src/compiler.jl:6745
 [11] _thunk
    @ ~/.julia/packages/Enzyme/S3nC6/src/compiler.jl:6743 [inlined]
 [12] cached_compilation
    @ ~/.julia/packages/Enzyme/S3nC6/src/compiler.jl:6801 [inlined]
 [13] thunkbase(mi::Core.MethodInstance, World::UInt64, FA::Type{…}, A::Type{…}, TT::Type, Mode::Enzyme.API.CDerivativeMode, width::Int64, ModifiedBetween::NTuple{…} where N, ReturnPrimal::Bool, ShadowInit::Bool, ABI::Type, ErrIfFuncWritten::Bool, RuntimeActivity::Bool, StrongZero::Bool, edges::Vector{…})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/S3nC6/src/compiler.jl:6917
 [14] thunk_generator(world::UInt64, source::Union{…}, FA::Type, A::Type, TT::Type, Mode::Enzyme.API.CDerivativeMode, Width::Int64, ModifiedBetween::NTuple{…} where N, ReturnPrimal::Bool, ShadowInit::Bool, ABI::Type, ErrIfFuncWritten::Bool, RuntimeActivity::Bool, StrongZero::Bool, self::Any, fakeworld::Any, fa::Type, a::Type, tt::Type, mode::Type, width::Type, modifiedbetween::Type, returnprimal::Type, shadowinit::Type, abi::Type, erriffuncwritten::Type, runtimeactivity::Type, strongzero::Type)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/S3nC6/src/compiler.jl:7061
 [15] autodiff
    @ ~/.julia/packages/Enzyme/S3nC6/src/Enzyme.jl:509 [inlined]
 [16] autodiff(mode::ReverseMode{false, false, false, FFIABI, false, false}, f::typeof(f), ::Type{Active}, args::Duplicated{Vector{Float64}})
    @ Enzyme ~/.julia/packages/Enzyme/S3nC6/src/Enzyme.jl:549
 [17] top-level scope
    @ REPL[9]:1
Some type information was truncated. Use `show(err)` to see complete types.

however, if you directly use a factorization such as

function f(b)
    A = Symmetric([4.0 1.0; 1.0 3.0])
    return sum(cholesky(A) \ b)
end

it works

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions