EnzymeAD / Enzyme.jl

Julia bindings for the Enzyme automatic differentiator
https://enzyme.mit.edu
MIT License
455 stars 63 forks source link

Enzyme.jl Error ```MethodError: no method matching ptreltype(::Type{Ptr})``` #1152

Closed matinraayai closed 11 months ago

matinraayai commented 11 months ago

I'm new to using Enzyme. I'm trying to differentiate the following piece of code:

using Redbird
using SparseArrays
using MATLAB
using Enzyme
########################################################
##   prepare simulation input
########################################################

function main()
    mat"addpath('./matlab/iso2mesh')"
    mat"addpath('./matlab/mcx')"

    prop = [0     0 1 1
    0.008 1 0 1.37
    0.016 1 0 1.37]
    prop = reshape(prop, 1, size(prop)...)

    cfg = Redbird.Structs.RBConfig()
    cfg.node, cfg.face, cfg.elem = mxcall(:meshabox, 3, [0 0 0], [60 60 30], 1)
    nn = size(cfg.node, 1)
    cfg.seg = ones(size(cfg.elem, 1), 1)

    (xi, yi) = mxcall(:meshgrid, 2, 60:20:140,20:20:100)

    cfg.srcpos = hcat(xi[:], yi[:], zeros(length(yi), 1))
    cfg.detpos = hcat(xi[:], yi[:], 60 * ones(length(yi), 1))
    cfg.srcdir = [0 0 1]
    cfg.detdir = [0 0 -1]

    # cfg.omega = 2 * pi * 70e6
    cfg.omega = [0]

    cfg.wavelengths = [""]

    function forward_solver(prop::Array{Float64}, 
        ∇ϕ_i∇ϕ_j::Array{Float64}, detval::Array{Float64})
        ########################################################
        ##   Build LHS
        ########################################################

        wavelengths = cfg.wavelengths

        Amat, ∇ϕ_i∇ϕ_j = Redbird.Forward.rbfemlhs(cfg, prop, ∇ϕ_i∇ϕ_j, 1)

        (rhs, loc, bary, optode) = Redbird.Forward.rbfemrhs(cfg, prop)
        # ########################################################
        # ##   Solve for solutions at all freenodes: Afree*sol=rhs
        # ########################################################
        ϕ = Redbird.Forward.rbfemsolve(Amat, rhs, :qmr)
        # ########################################################
        # ##   Extract detector readings from the solutions
        # ########################################################

        (detval, goodix) = Redbird.Forward.rbfemgetdet(ϕ, cfg, loc, bary)
        return nothing
    end

    cfg = Redbird.Forward.rbmeshprep(cfg, prop)
    ∇s = Redbird.Forward.rb∇̇ϕ_i∇ϕ_j(cfg)
    ∇ϕ_i∇ϕ_j = ∇s.∇ϕ_i∇ϕ_j
    d_∇ϕ_i∇ϕ_j = similar(∇ϕ_i∇ϕ_j)
    # ∇ϕ = ∇s.∇ϕ

    dprop = zeros(Float64, 1, 3, 4)

    detval = zeros(Float64, 25, 25)

    d_detval = ones(Float64, 25, 25)
    # Enzyme.API.runtimeActivity!(true)
    # forward_solver(prop, cfg, ∇ϕ_i∇ϕ_j, detval)
    Enzyme.autodiff(Reverse, forward_solver, Duplicated(prop, dprop),
    Duplicated(∇ϕ_i∇ϕ_j, d_∇ϕ_i∇ϕ_j),
    Duplicated(detval, d_detval));

    @show dprop
end

main()

My goal is to take the derivative of detval w.r.t prop so I can optimize prop to match a particular detval (MSE loss not included here)

I get the following error:

ERROR: LoadError: MethodError: no method matching ptreltype(::Type{Ptr})

Closest candidates are:
  ptreltype(::Type{Ptr{T}}) where T
   @ Enzyme ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:285
  ptreltype(::Type{Core.LLVMPtr{T, N}}) where {T, N}
   @ Enzyme ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:286
  ptreltype(::Type{Base.RefValue{T}}) where T
   @ Enzyme ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:287
  ...

Stacktrace:
  [1] active_reg_inner
    @ ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:365 [inlined]
  [2] active_reg_inner (repeats 2 times)
    @ ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:344 [inlined]
  [3] guaranteed_const_nongen(#unused#::Type{Ptr}, world::UInt64)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:481
  [4] julia_activity_rule(f::LLVM.Function)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:7402
  [5] codegen(output::Symbol, job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget, Enzyme.Compiler.EnzymeCompilerParams}; libraries::Bool, deferred_codegen::Bool, optimize::Bool, toplevel::Bool, strip::Bool, validate::Bool, only_entry::Bool, parent_job::Nothing)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:9065
  [6] codegen
    @ ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:8886 [inlined]
  [7] _thunk(job::GPUCompiler.CompilerJob{Enzyme.Compiler.EnzymeTarget, Enzyme.Compiler.EnzymeCompilerParams}, postopt::Bool)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:9830
  [8] _thunk
    @ ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:9830 [inlined]
  [9] cached_compilation
    @ ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:9864 [inlined]
 [10] (::Enzyme.Compiler.var"#474#475"{DataType, DataType, DataType, Enzyme.API.CDerivativeMode, NTuple{4, Bool}, Int64, Bool, Bool, UInt64, DataType})(ctx::LLVM.Context)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:9921
 [11] JuliaContext(f::Enzyme.Compiler.var"#474#475"{DataType, DataType, DataType, Enzyme.API.CDerivativeMode, NTuple{4, Bool}, Int64, Bool, Bool, UInt64, DataType})
    @ GPUCompiler ~/.julia/packages/GPUCompiler/U36Ed/src/driver.jl:47
 [12] #s325#473
    @ ~/.julia/packages/Enzyme/rbuCz/src/compiler.jl:9882 [inlined]
 [13] var"#s325#473"(FA::Any, A::Any, TT::Any, Mode::Any, ModifiedBetween::Any, width::Any, ReturnPrimal::Any, ShadowInit::Any, World::Any, ABI::Any, ::Any, #unused#::Type, #unused#::Type, #unused#::Type, tt::Any, #unused#::Type, #unused#::Type, #unused#::Type, #unused#::Type, #unused#::Type, #unused#::Any)
    @ Enzyme.Compiler ./none:0
 [14] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any})
    @ Core ./boot.jl:602
 [15] autodiff(::ReverseMode{false, FFIABI}, ::Const{var"#forward_solver#3"}, ::Type{Const{Nothing}}, ::Duplicated{Array{Float64, 3}}, ::Vararg{Any})
    @ Enzyme ~/.julia/packages/Enzyme/rbuCz/src/Enzyme.jl:207
 [16] autodiff(::ReverseMode{false, FFIABI}, ::Const{var"#forward_solver#3"}, ::Duplicated{Array{Float64, 3}}, ::Duplicated{Matrix{Float64}}, ::Vararg{Duplicated{Matrix{Float64}}})
    @ Enzyme ~/.julia/packages/Enzyme/rbuCz/src/Enzyme.jl:236
 [17] autodiff
    @ ~/.julia/packages/Enzyme/rbuCz/src/Enzyme.jl:222 [inlined]
 [18] main()
    @ Main /scratch/raayaiardakani.m/Redbird.jl/example/redbird_enzyme.jl:78
 [19] top-level scope
    @ /scratch/raayaiardakani.m/Redbird.jl/example/redbird_enzyme.jl:85
in expression starting at /scratch/raayaiardakani.m/Redbird.jl/example/redbird_enzyme.jl:85

Here cfg is a Dict{Symbol, Any} wrapper that mimics Matlab structs and Matlab struct methods in Julia. RedBird is a tool I ported from Matlab to differentiate. Even though the part I differentiate is in pure Julia, some of the cfg inputs still need some pre-processing from Matlab.

cfg and ∇ϕ_i∇ϕ_j should remain constant and I don't want their derivatives. I've tried many other ways (making them Const instead of Duplicated) but I still get the same error.

Also a warning that the computation does involve SparseArrays and I need a way to fix it with the make_zeros function for Enzyme to work, although I doubt this has anything to do with the error here.

Thanks in advance @wsmoses

wsmoses commented 11 months ago

This error was fixed by the linked PR, closing

wsmoses commented 11 months ago

@matinraayai since you had a different issue arise for the full code, can you create another issue for it (with a full code reproducer)?

matinraayai commented 11 months ago

Sure @wsmoses