Skip to content

Enzyme not compatible with Ark #2851

@ameligrana

Description

@ameligrana

I was trying to compute the gradient for a simple program in Ark but I got warnings and errors which I think hint on a deeper problem in the automatic differentiation of this code with Enzyme. Notice that the code works with Mooncake instead

julia> using Ark, Enzyme, DifferentiationInterface

julia> struct Position
           x::Float64
           y::Float64
       end

julia> struct Velocity
           dx::Float64
           dy::Float64
       end

julia> function run_world(args)
           alpha, beta = args
           world = World(Position, Velocity)

           entities = Entity[]
           sizehint!(entities, 100)
           for i in 1:100
               entity = new_entity!(world, (Position(i, i * 2),))
               push!(entities, entity)
           end

           for e in entities
               add_components!(world, e, (Velocity(1, 1),))
           end

           for i in 1:10
               for (entities, positions, velocities) in Query(world, (Position, Velocity))
                   @inbounds for i in eachindex(entities)
                       pos = positions[i]
                       vel = velocities[i]
                       positions[i] = Position(alpha * (pos.x + vel.dx), beta * (pos.y + vel.dy))
                   end
               end
           end

           all_positions = Position[]
           for (entities, positions) in Query(world, (Position,))
               append!(all_positions, positions)
           end

           return sum(pos.x + pos.y for pos in all_positions)
       end
run_world (generic function with 1 method)

julia> backend = AutoEnzyme()
AutoEnzyme()

julia> g = DifferentiationInterface.gradient(run_world, backend, (0.1, 0.5))
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type of (false, nothing) in   %arrayref = load {} addrspace(10)*, {} addrspace(10)* addrspace(13)* %13, align 8, !dbg !141, !tbaa !152, !alias.scope !104, !noalias !107, !enzyme_type !154 
│ Caused by:
│ Stacktrace:
│  [1] _deleteend!
│    @ ./array.jl:1081
│  [2] pop!
│    @ ./array.jl:1401
│  [3] _swap_remove!
│    @ ~/.julia/dev/Ark/src/util.jl:8
│  [4] _move_component_data!
│    @ ~/.julia/dev/Ark/src/storage.jl:67
│  [5] macro expansion
│    @ ~/.julia/dev/Ark/src/util.jl:92
│  [6] macro expansion
│    @ ~/.julia/dev/Ark/src/world.jl:1946
│  [7] _move_component_data!
│    @ ~/.julia/dev/Ark/src/world.jl:1946
└ @ Enzyme.Compiler ~/.julia/packages/Enzyme/i91IH/src/rules/llvmrules.jl:1708
┌ Warning: TODO reverse jl_array_del_end zero-set used memset rather than runtime type of (false, nothing) in   %arrayref37 = load {} addrspace(10)*, {} addrspace(10)* addrspace(13)* %24, align 8, !dbg !141, !tbaa !152, !alias.scope !104, !noalias !107, !enzyme_type !154 
│ Caused by:
│ Stacktrace:
│  [1] _deleteend!
│    @ ./array.jl:1081
│  [2] pop!
│    @ ./array.jl:1401
│  [3] _swap_remove!
│    @ ~/.julia/dev/Ark/src/util.jl:8
│  [4] _move_component_data!
│    @ ~/.julia/dev/Ark/src/storage.jl:67
│  [5] macro expansion
│    @ ~/.julia/dev/Ark/src/util.jl:92
│  [6] macro expansion
│    @ ~/.julia/dev/Ark/src/world.jl:1946
│  [7] _move_component_data!
│    @ ~/.julia/dev/Ark/src/world.jl:1946
└ @ Enzyme.Compiler ~/.julia/packages/Enzyme/i91IH/src/rules/llvmrules.jl:1708
ERROR: EnzymeRuntimeActivityError: Detected potential need for runtime activity.

Constant memory is stored (or returned) to a differentiable variable and correctness cannot be guaranteed with static activity analysis.
This might be due to the use of a constant variable as temporary storage for active memory (https://enzyme.mit.edu/julia/stable/faq/#Runtime-Activity).
If Enzyme should be able to prove this use non-differentable, open an issue!

To work around this issue, either:
   a) rewrite this variable to not be conditionally active (fastest performance, slower to setup), or
   b) set the Enzyme mode to turn on runtime activity (e.g. autodiff(set_runtime_activity(Reverse), ...) ). This will maintain correctness, but may slightly reduce performance.

Failure within method:

Ark._Archetype(::UInt32, ::Ark._GraphNode{1}, ::UInt32)
     @ Ark ~/.julia/dev/Ark/src/archetype.jl:40

Hint: catch this exception as `err` and call `code_typed(err)` to inspect the surrounding code.

Mismatched activity for:   store {} addrspace(10)* %13, {} addrspace(10)* addrspace(11)* %26, align 8, !dbg !164, !tbaa !166, !alias.scope !148, !noalias !149 const val:   %13 = call fastcc noalias nonnull align 8 dereferenceable(64) {} addrspace(10)* @julia_Dict_2778() #114, !dbg !162
Type tree: {[-1]:Pointer, [-1,0]:Pointer, [-1,0,0]:Pointer, [-1,0,8]:Integer, [-1,0,9]:Integer, [-1,0,10]:Integer, [-1,0,11]:Integer, [-1,0,12]:Integer, [-1,0,13]:Integer, [-1,0,14]:Integer, [-1,0,15]:Integer, [-1,0,16]:Integer, [-1,0,17]:Integer, [-1,0,18]:Integer, [-1,0,19]:Integer, [-1,0,20]:Integer, [-1,0,21]:Integer, [-1,0,22]:Integer, [-1,0,23]:Integer, [-1,0,24]:Integer, [-1,0,25]:Integer, [-1,0,26]:Integer, [-1,0,27]:Integer, [-1,0,28]:Integer, [-1,0,29]:Integer, [-1,0,30]:Integer, [-1,0,31]:Integer, [-1,0,32]:Integer, [-1,0,33]:Integer, [-1,0,34]:Integer, [-1,0,35]:Integer, [-1,0,36]:Integer, [-1,0,37]:Integer, [-1,0,38]:Integer, [-1,0,39]:Integer, [-1,8]:Pointer, [-1,8,0]:Pointer, [-1,8,0,-1]:Integer, [-1,8,8]:Integer, [-1,8,9]:Integer, [-1,8,10]:Integer, [-1,8,11]:Integer, [-1,8,12]:Integer, [-1,8,13]:Integer, [-1,8,14]:Integer, [-1,8,15]:Integer, [-1,8,16]:Integer, [-1,8,17]:Integer, [-1,8,18]:Integer, [-1,8,19]:Integer, [-1,8,20]:Integer, [-1,8,21]:Integer, [-1,8,22]:Integer, [-1,8,23]:Integer, [-1,8,24]:Integer, [-1,8,25]:Integer, [-1,8,26]:Integer, [-1,8,27]:Integer, [-1,8,28]:Integer, [-1,8,29]:Integer, [-1,8,30]:Integer, [-1,8,31]:Integer, [-1,8,32]:Integer, [-1,8,33]:Integer, [-1,8,34]:Integer, [-1,8,35]:Integer, [-1,8,36]:Integer, [-1,8,37]:Integer, [-1,8,38]:Integer, [-1,8,39]:Integer, [-1,16]:Pointer, [-1,16,0]:Pointer, [-1,16,0,-1]:Integer, [-1,16,8]:Integer, [-1,16,9]:Integer, [-1,16,10]:Integer, [-1,16,11]:Integer, [-1,16,12]:Integer, [-1,16,13]:Integer, [-1,16,14]:Integer, [-1,16,15]:Integer, [-1,16,16]:Integer, [-1,16,17]:Integer, [-1,16,18]:Integer, [-1,16,19]:Integer, [-1,16,20]:Integer, [-1,16,21]:Integer, [-1,16,22]:Integer, [-1,16,23]:Integer, [-1,16,24]:Integer, [-1,16,25]:Integer, [-1,16,26]:Integer, [-1,16,27]:Integer, [-1,16,28]:Integer, [-1,16,29]:Integer, [-1,16,30]:Integer, [-1,16,31]:Integer, [-1,16,32]:Integer, [-1,16,33]:Integer, [-1,16,34]:Integer, [-1,16,35]:Integer, [-1,16,36]:Integer, [-1,16,37]:Integer, [-1,16,38]:Integer, [-1,16,39]:Integer, [-1,24]:Integer, [-1,25]:Integer, [-1,26]:Integer, [-1,27]:Integer, [-1,28]:Integer, [-1,29]:Integer, [-1,30]:Integer, [-1,31]:Integer, [-1,32]:Integer, [-1,33]:Integer, [-1,34]:Integer, [-1,35]:Integer, [-1,36]:Integer, [-1,37]:Integer, [-1,38]:Integer, [-1,39]:Integer, [-1,40]:Integer, [-1,41]:Integer, [-1,42]:Integer, [-1,43]:Integer, [-1,44]:Integer, [-1,45]:Integer, [-1,46]:Integer, [-1,47]:Integer, [-1,48]:Integer, [-1,49]:Integer, [-1,50]:Integer, [-1,51]:Integer, [-1,52]:Integer, [-1,53]:Integer, [-1,54]:Integer, [-1,55]:Integer, [-1,56]:Integer, [-1,57]:Integer, [-1,58]:Integer, [-1,59]:Integer, [-1,60]:Integer, [-1,61]:Integer, [-1,62]:Integer, [-1,63]:Integer}
 LLVM view of erring value:     %13 = call fastcc noalias nonnull align 8 dereferenceable(64) {} addrspace(10)* @julia_Dict_2778() #114, !dbg !162

Stacktrace:
 [1] _Archetype
   @ ~/.julia/dev/Ark/src/archetype.jl:29
 [2] _Archetype
   @ ~/.julia/dev/Ark/src/archetype.jl:41

Stacktrace:
  [1] _Archetype
    @ ~/.julia/dev/Ark/src/archetype.jl:29 [inlined]
  [2] _Archetype
    @ ~/.julia/dev/Ark/src/archetype.jl:41
  [3] macro expansion
    @ ~/.julia/dev/Ark/src/world.jl:776 [inlined]
  [4] _World_from_types
    @ ~/.julia/dev/Ark/src/world.jl:687
  [5] #World#111
    @ ~/.julia/dev/Ark/src/world.jl:118 [inlined]
  [6] World
    @ ~/.julia/dev/Ark/src/world.jl:114 [inlined]
  [7] run_world
    @ ./REPL[4]:3 [inlined]
  [8] run_world
    @ ./REPL[4]:0 [inlined]
  [9] diffejulia_run_world_2676_inner_1wrap
    @ ./REPL[4]:0
 [10] macro expansion
    @ ~/.julia/packages/Enzyme/i91IH/src/compiler.jl:6652 [inlined]
 [11] enzyme_call
    @ ~/.julia/packages/Enzyme/i91IH/src/compiler.jl:6131 [inlined]
 [12] CombinedAdjointThunk
    @ ~/.julia/packages/Enzyme/i91IH/src/compiler.jl:6015 [inlined]
 [13] autodiff
    @ ~/.julia/packages/Enzyme/i91IH/src/Enzyme.jl:521 [inlined]
 [14] autodiff
    @ ~/.julia/packages/Enzyme/i91IH/src/Enzyme.jl:542 [inlined]
 [15] macro expansion
    @ ~/.julia/packages/Enzyme/i91IH/src/sugar.jl:344 [inlined]
 [16] gradient
    @ ~/.julia/packages/Enzyme/i91IH/src/sugar.jl:274 [inlined]
 [17] gradient
    @ ~/.julia/packages/DifferentiationInterface/4n6vR/ext/DifferentiationInterfaceEnzymeExt/reverse_onearg.jl:237 [inlined]
 [18] gradient(::typeof(run_world), ::AutoEnzyme{Nothing, Nothing}, ::Tuple{Float64, Float64})
    @ DifferentiationInterface ~/.julia/packages/DifferentiationInterface/4n6vR/src/first_order/gradient.jl:63
 [19] top-level scope
    @ REPL[6]:1

I used Enzyme v0.13.109 and Julia 1.10.10 in this example.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions