Skip to content

Duplicated function failure with matrix view #2532

@gdalle

Description

@gdalle

I just noticed this failure while debugging #2531. I don't see it during CI so maybe it only happens on my Mac? Can someone reproduce on Linux?

The example below might seem convoluted, but it is very useful to the DI test suite for functions that close over writable active data.

using Enzyme

function num_to_vec!(y::AbstractVector, x::Number)
    view(y, :) .= x
    return nothing
end

function num_to_mat!(y::AbstractMatrix, x::Number)
    view(y, :, :) .= x  # with y .= x the code works
    return nothing
end

struct WritableClosure{F,Y}
    f!::F
    y_buffer::Y
end

function (wc::WritableClosure)(y::AbstractArray, x::Number)
    (; f!, y_buffer) = wc
    f!(y_buffer[1], x)
    copyto!(y, y_buffer[1])
    return nothing
end

x = 1.0
yv = zeros(2)
ym = zeros(2, 2)
yv_buffer = [zero(yv)]
ym_buffer = [zero(ym)]

fv! = WritableClosure(num_to_vec!, yv_buffer)
fm! = WritableClosure(num_to_mat!, ym_buffer)

fv!(yv, x)  # works
fm!(ym, x)  # works

autodiff(
    Forward,
    Duplicated(fv!, make_zero(fv!)),
    Duplicated(yv, zero(yv)),
    Duplicated(x, one(x))
)  # works

autodiff(
    Forward,
    Duplicated(fm!, make_zero(fm!)),
    Duplicated(ym, zero(ym)),
    Duplicated(x, one(x))
)  # fails

Stack trace:

julia> autodiff(
           Forward,
           Duplicated(fm!, make_zero(fm!)),
           Duplicated(ym, zero(ym)),
           Duplicated(x, one(x))
       )  # fails
ERROR: Enzyme compilation failed due to an internal error.
 Please open an issue with the code to reproduce and full error log on github.com/EnzymeAD/Enzyme.jl
 To toggle more information for debugging (needed for bug reports), set Enzyme.Compiler.VERBOSE_ERRORS[] = true (default false)

Stacktrace:
 [1] ==
   @ ./promotion.jl:639
 [2] _copyto_impl!
   @ ./array.jl:302
 [3] copyto!
   @ ./array.jl:299
 [4] copyto!
   @ ./array.jl:322
 [5] WritableClosure
   @ ~/Documents/GitHub/Julia/Enzyme.jl/test/integration/DifferentiationInterface/playground.jl:21
 [6] WritableClosure
   @ ~/Documents/GitHub/Julia/Enzyme.jl/test/integration/DifferentiationInterface/playground.jl:0

Stacktrace:
  [1] julia_error(msg::String, val::Ptr{…}, errtype::Enzyme.API.ErrorType, data::Ptr{…}, data2::Ptr{…}, B::Ptr{…})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/iosr4/src/errors.jl:461
  [2] julia_error(cstr::Cstring, val::Ptr{…}, errtype::Enzyme.API.ErrorType, data::Ptr{…}, data2::Ptr{…}, B::Ptr{…})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/iosr4/src/errors.jl:299
  [3] EnzymeCreateForwardDiff(logic::Enzyme.Logic, todiff::LLVM.Function, retType::Enzyme.API.CDIFFE_TYPE, constant_args::Vector{…}, TA::Enzyme.TypeAnalysis, returnValue::Bool, mode::Enzyme.API.CDerivativeMode, runtimeActivity::Bool, strongZero::Bool, width::Int64, additionalArg::Ptr{…}, typeInfo::Enzyme.FnTypeInfo, uncacheable_args::Vector{…})
    @ Enzyme.API ~/.julia/packages/Enzyme/iosr4/src/api.jl:342
  [4] enzyme!(job::GPUCompiler.CompilerJob{…}, 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{…})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/iosr4/src/compiler.jl:2524
  [5] compile_unhooked(output::Symbol, job::GPUCompiler.CompilerJob{…})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/iosr4/src/compiler.jl:4900
  [6] compile(target::Symbol, job::GPUCompiler.CompilerJob; kwargs::@Kwargs{})
    @ GPUCompiler ~/.julia/packages/GPUCompiler/Ecaql/src/driver.jl:67
  [7] compile
    @ ~/.julia/packages/GPUCompiler/Ecaql/src/driver.jl:55 [inlined]
  [8] _thunk(job::GPUCompiler.CompilerJob{…}, postopt::Bool)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/iosr4/src/compiler.jl:5763
  [9] _thunk
    @ ~/.julia/packages/Enzyme/iosr4/src/compiler.jl:5761 [inlined]
 [10] cached_compilation
    @ ~/.julia/packages/Enzyme/iosr4/src/compiler.jl:5815 [inlined]
 [11] 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/iosr4/src/compiler.jl:5929
 [12] 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/iosr4/src/compiler.jl:6122
 [13] autodiff
    @ ~/.julia/packages/Enzyme/iosr4/src/Enzyme.jl:654 [inlined]
 [14] autodiff(::ForwardMode{…}, ::Duplicated{…}, ::Duplicated{…}, ::Duplicated{…})
    @ Enzyme ~/.julia/packages/Enzyme/iosr4/src/Enzyme.jl:558
 [15] top-level scope
    @ ~/Documents/GitHub/Julia/Enzyme.jl/test/integration/DifferentiationInterface/playground.jl:44
Some type information was truncated. Use `show(err)` to see complete types.

Complete stack trace:

log.txt

Setup:

(jl_ONCLNM) pkg> st
Status `/private/var/folders/pt/myrxq2gs5hzcp79v5475_dh40000gp/T/jl_ONCLNM/Project.toml`
  [7da242da] Enzyme v0.13.69

julia> versioninfo()
Julia Version 1.11.6
Commit 9615af0f269 (2025-07-09 12:58 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin24.0.0)
  CPU: 11 × Apple M3 Pro
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, apple-m2)
Threads: 5 default, 0 interactive, 2 GC (on 5 virtual cores)
Environment:
  JULIA_EDITOR = code
  JULIA_VSCODE_REPL = 1

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