Skip to content

hcat broken in Enzyme? #2524

@StephenVavasis

Description

@StephenVavasis

See the MWE below. The first test run simulates hcat by storing entries in a matrix in consecutive column numbers, and this works. The second test run actually uses hcat and breaks Enzyme.

Source code:

module enzyme_test

using Enzyme

function use_hcat(x)
    w = zeros(length(x), length(x))
    for i = 1 : length(x)
        w[:,i] .= x
    end
    p = hcat(w, x)
    return sum(p)
end

function dont_use_hcat(x)
    w = zeros(length(x), length(x))
    for i = 1 : length(x)
        w[:,i] .= x
    end
    p = zeros(length(x), length(x) + 1)
    p[:, 1:length(x)] .= w
    p[:, length(x) + 1] .= x
    return sum(p)
end

function deriv1(use_hcat_p)
    x = [1.0, 2.0, 4.0]
    dx = [1.0, 0.0, 0.0]
    if use_hcat_p
        println("function val using hcat = ", use_hcat(x))
        s = autodiff(Forward,
                     use_hcat,
                     Duplicated(x, dx))
    else
        println("function val not using hcat = ", dont_use_hcat(x))
        s = autodiff(Forward,
                     dont_use_hcat,
                     Duplicated(x, dx))
    end
    return s[1]
end
end

Test runs:

julia> include("enzymetest.jl")
WARNING: replacing module enzyme_test.
Main.enzyme_test

julia> enzyme_test.deriv1(false)
function val not using hcat = 28.0
4.0

julia> enzyme_test.deriv1(true)
function val using hcat = 28.0
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] length
   @ .\essentials.jl:12
 [2] _typed_hcat
   @ .\abstractarray.jl:1702

Stacktrace:
  [1] julia_error(msg::String, val::Ptr{…}, errtype::Enzyme.API.ErrorType, data::Ptr{…}, data2::Ptr{…}, B::Ptr{…})
    @ Enzyme.Compiler C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\errors.jl:461
  [2] julia_error(cstr::Cstring, val::Ptr{…}, errtype::Enzyme.API.ErrorType, data::Ptr{…}, data2::Ptr{…}, B::Ptr{…})
    @ Enzyme.Compiler C:\Users\vavasis\.julia\packages\Enzyme\LMVya\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 C:\Users\vavasis\.julia\packages\Enzyme\LMVya\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 C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\compiler.jl:2514
  [5] compile_unhooked(output::Symbol, job::GPUCompiler.CompilerJob{…})
    @ Enzyme.Compiler C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\compiler.jl:4834
  [6] compile(target::Symbol, job::GPUCompiler.CompilerJob; kwargs::@Kwargs{})
    @ GPUCompiler C:\Users\vavasis\.julia\packages\GPUCompiler\Ecaql\src\driver.jl:67
  [7] compile
    @ C:\Users\vavasis\.julia\packages\GPUCompiler\Ecaql\src\driver.jl:55 [inlined]
  [8] _thunk(job::GPUCompiler.CompilerJob{…}, postopt::Bool)
    @ Enzyme.Compiler C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\compiler.jl:5697
  [9] _thunk
    @ C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\compiler.jl:5695 [inlined]
 [10] cached_compilation
    @ C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\compiler.jl:5749 [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 C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\compiler.jl:5863
 [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 C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\compiler.jl:6056
 [13] autodiff
    @ C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\Enzyme.jl:654 [inlined]
 [14] autodiff
    @ C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\Enzyme.jl:558 [inlined]
 [15] autodiff
    @ C:\Users\vavasis\.julia\packages\Enzyme\LMVya\src\Enzyme.jl:530 [inlined]
 [16] deriv1(use_hcat_p::Bool)
    @ Main.enzyme_test c:\Users\vavasis\OneDrive - University of Waterloo\Katerina\myosin\enzymetest.jl:30
 [17] top-level scope
    @ REPL[161]:1
Some type information was truncated. Use `show(err)` to see complete types.

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