If EnzymeRules.inactive() is defined, does the Enzyme.jl operation still take place?

When performing automatic differentiation using Enzyme.jl, Errors and warnings occur in functions that define EnzymeRules.inactive().

I thought that the application of Enzyme.jl was ignored when EnzymeRules.inactive() was used.
But is that not the case, and Enzyme.jl is applied and simply the return value of the function is treated as a constant?

Marking a function as inactive in Enzyme means that it won’t be differentiated. The original function call will still be run (as its values may be needed/produce observable side effects/etc)

Does that mean that if I use a function marked inactive() but not supported by Enzyme.jl, I will get an error?

Generally marking it as inactive means most Enzyme errors will go away (since we don’t need to differentiate it).

Not all may go away, however. For example if Julia generates some weird GC we don’t tunderstand Enzyme will throw an error rather than risk a segfault.

So it depends – what error are you seeing?

Since we are running this in a larger program, it may not be common, but it should show the warnings and errors that are being output.

  • Warning (This occurs often in Enzyme.jl.)
┌ Warning: Using fallback BLAS replacements for (["dsymv_64_", "dsyrk_64_"]), performance may be degraded
└ @ Enzyme.Compiler ~/.julia/packages/GPUCompiler/kqxyC/src/utils.jl:59
  • Error Description
    The following error does not occur on macOS, but does occur on Linux (Ubuntu).
    Note that the function make_boundary_Ks_and_Fs(), which is in error, is also marked as inactive().
    The part of the vector that is in direct error is the part where the vector is zero-cleared.
 Fe = zeros(Float64, num_dof)
ERROR: Enzyme execution failed.
Mismatched activity for:   %value_phi33 = phi {} addrspace(10)* [ %62, %L101 ], [ %66, %L104 ] 
const val:   %62 = call fastcc nonnull {} addrspace(10)* @julia_make_dNdxi_16061({ i64, i64, {} addrspace(10)*, {} addrspace(10)*, i64, {} addrspace(10)*, {} addrspace(10)*, double, i64, {} addrspace(10)*, i64, {} addrspace(10)*, {} addrspace(10)* } addrspace(11)* noalias nocapture nofree nonnull readnone align 8 dereferenceable(104) undef, {} addrspace(10)* nofree noundef nonnull align 16 dereferenceable(40) %57) #128, !dbg !263
value=Unknown object of type Matrix{Float64}
You may be using a constant variable as temporary storage for active memory (https://enzyme.mit.edu/julia/stable/faq/#Activity-of-temporary-storage). If not, please open an issue, and either rewrite this variable to not be conditionally active or use Enzyme.API.runtimeActivity!(true) as a workaround for now

Stacktrace is as follows:

Stacktrace:
  [1] throwerr(cstr::Cstring)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/MIIMf/src/compiler.jl:1285
  [2] iterate
    @ ./range.jl:901 [inlined]
  [3] fill!
    @ ./array.jl:396 [inlined]
  [4] zeros
    @ ./array.jl:637 [inlined]
  [5] zeros
    @ ./array.jl:632 [inlined]
  [6] make_boundary_Ke_and_Fe
    @ ~/my_programs/JuliaOptOS/src/EnzymeOptOS/solid_mechanics/element/structural_quad4_boundary.jl:54
  [7] make_boundary_Ks_and_Fs
    @ ~/my_programs/JuliaOptOS/src/EnzymeOptOS/solid_mechanics/boundary_condition/robin_bc.jl:31
  [8] dynamic_structural_compliance_pnorm
    @ ~/my_programs/JuliaOptOS/src/EnzymeOptOS/evaluate_functions/dynamic_linear_elastic_systems/dynamic_structural_compliance_pnorm.jl:81
  [9] f
    @ ~/my_programs/JuliaOptOS/src/EnzymeOptOS/evaluate_functions/dynamic_linear_elastic_systems/dynamic_structural_compliance_pnorm.jl:21 [inlined]
 [10] f
    @ ~/my_programs/JuliaOptOS/src/EnzymeOptOS/evaluate_functions/dynamic_linear_elastic_systems/dynamic_structural_compliance_pnorm.jl:0 [inlined]
 [11] diffejulia_f_15729_inner_12wrap
    @ ~/my_programs/JuliaOptOS/src/EnzymeOptOS/evaluate_functions/dynamic_linear_elastic_systems/dynamic_structural_compliance_pnorm.jl:0
 [12] macro expansion
    @ ~/.julia/packages/Enzyme/MIIMf/src/compiler.jl:5594 [inlined]
 [13] enzyme_call(::Val{…}, ::Ptr{…}, ::Type{…}, ::Type{…}, ::Val{…}, ::Type{…}, ::Type{…}, ::EnzymeCore.Const{…}, ::Type{…}, ::EnzymeCore.Duplicated{…}, ::Float64)
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/MIIMf/src/compiler.jl:5272
 [14] (::Enzyme.Compiler.CombinedAdjointThunk{…})(::EnzymeCore.Const{…}, ::EnzymeCore.Duplicated{…}, ::Vararg{…})
    @ Enzyme.Compiler ~/.julia/packages/Enzyme/MIIMf/src/compiler.jl:5154
 [15] autodiff
    @ ~/.julia/packages/Enzyme/MIIMf/src/Enzyme.jl:275 [inlined]
 [16] autodiff
    @ ~/.julia/packages/Enzyme/MIIMf/src/Enzyme.jl:287 [inlined]
 [17] gradient
    @ ~/.julia/packages/Enzyme/MIIMf/src/Enzyme.jl:938 [inlined]
 [18] (::Main.SolidMechanicsTO.var"#df#114"{Main.SolidMechanicsTO.var"#f#113"{…}})(x::Vector{Float64})
    @ Main.SolidMechanicsTO ~/my_programs/JuliaOptOS/src/EnzymeOptOS/evaluate_functions/dynamic_linear_elastic_systems/dynamic_structural_compliance_pnorm.jl:24
 [19] (::Main.SolidMechanicsTO.var"#df_obj_min#58"{…})(x::Vector{…})
    @ Main.SolidMechanicsTO ~/my_programs/JuliaOptOS/src/EnzymeOptOS/optimization/optimizers/MMA_GCMMA/abstract_basic_MMA.jl:16
 [20] (::Main.SolidMechanicsTO.var"#54#60"{Main.SolidMechanicsTO.var"#df_obj_min#58"{…}})(x::Vector{Float64})
    @ Main.SolidMechanicsTO ~/my_programs/JuliaOptOS/src/EnzymeOptOS/optimization/optimizers/MMA_GCMMA/abstract_basic_MMA.jl:19
 [21] compute(opt::Main.SolidMechanicsTO.GCMMA, s::Vector{Float64})
    @ Main.SolidMechanicsTO ~/my_programs/JuliaOptOS/src/EnzymeOptOS/optimization/optimizers/MMA_GCMMA/abstract_basic_MMA.jl:57
 [22] my_optimize(opt::Main.SolidMechanicsTO.GCMMA, xval::Vector{…}, nodes::Vector{…}, elements::Vector{…}, filter::Main.SolidMechanicsTO.DensityFilter)
    @ Main.SolidMechanicsTO ~/my_programs/JuliaOptOS/src/EnzymeOptOS/optimization/optimizers/MMA_GCMMA/GCMMA_wrapper.jl:96
 [23] main()
    @ Main ~/my_programs/JuliaOptOS/examples/EnzymeOptOS/dynamic_structural_compliance_2norm_my_optimizer.jl:150
 [24] top-level scope
    @ ~/my_programs/JuliaOptOS/examples/EnzymeOptOS/dynamic_structural_compliance_2norm_my_optimizer.jl:257
Some type information was truncated. Use `show(err)` to see complete types.

Can you share your entire erring application, perhaps as an issue on Enzyme.jl?

From the looks of it make_boundary_Ks_and_Fs was not recognized as inactive, so my guess is that your custom activity rule is messed up

Sorry, the arguments were incorrectly set in my program and inactive() was recognised as a different function. However, the modifications have not eliminated the current errors.

I will review it a bit more on my end and add it to the Enzyme.jl issue if there is a problem.