When the reverse mode of Enzyme.jl was run, the following error was displayed.
What are the main causes of the following error messages?
Does anyone know the general reason for what causes it?
“mutable struct” is created within the scope of application of automatic differentiation and its member variables are changed.
The type of the member variable is Matrix{Float64}.
ERROR: Enzyme execution failed.
Enzyme could not find shadow for value
Current scope:
preprocess_julia_setup_12036_inner.1{} addrspace(10)* ({ i64, {} addrspace(10)*, {} addrspace(10)*, {} addrspace(10)*, {} addrspace(10)*, {} addrspace(10)*, double }, {} addrspace(10)*, i64)
cannot find shadow for { i64, {} addrspace(10)*, {} addrspace(10)*, {} addrspace(10)*, {} addrspace(10)*, {} addrspace(10)*, double } %0
I wrote a very simplified test program.
The “mutable struct” is shown below, but the following program works fine.
In fact, I think the error is due to interactions with others as they are used in more complex, larger programs.
using LinearAlgebra
using Enzyme
#--------------------------------------------------------------------------------
#
#--------------------------------------------------------------------------------
mutable struct Container
# menber
matrix1::Matrix{Float64}
matrix2::Matrix{Float64}
#----------------------------------------------
# inner constractor
#----------------------------------------------
function Container()
return new(zeros(Float64, 2, 2), zeros(Float64, 2, 2))
end
end
#--------------------------------------------------------------------------------
#
#--------------------------------------------------------------------------------
mutable struct Element
# menber
containers::Vector{Container}
#----------------------------------------------
# inner constractor
#----------------------------------------------
function Element(num::Int64)
containers = Vector{Container}(undef, num)
for i in 1 : num
containers[i] = Container()
end
return new(containers)
end
end
#--------------------------------------------------------------------------------
#
#--------------------------------------------------------------------------------
function test_func(x)
# create
elements = Vector{Element}(undef, length(x))
for i in 1 : length(x)
elements[i] = Element(4)
end
# main part
value = 0.0
for iter in 1 : 10
coeff1 = Float64(iter)
for (e, element) in enumerate(elements)
for (c, container) in enumerate(element.containers)
coeff2 = Float64(c)
# update
container.matrix1[1, 1] = container.matrix2[1, 1] + x[e]
container.matrix1[1, 2] = container.matrix2[1, 1] + x[e]^coeff1
container.matrix1[2, 1] = container.matrix2[1, 1] + x[e]^3.0 - coeff2 * x[length(x)]
container.matrix1[2, 2] = container.matrix2[1, 1] + coeff1 * x[e] + 2.0 * x[1]^coeff2
# calculate
value += dot(x[1] * container.matrix1, coeff2 * x[3] * x[e] * container.matrix1)
# update
container.matrix2 = container.matrix1
end
end
end
return value
end
#--------------------------------------------------------------------------------
#
#--------------------------------------------------------------------------------
function main()
#
x0 = rand(4)
# exe
value = test_func(x0)
display(value)
# autodiff
df = gradient(Reverse, test_func, x0)
display(df)
end
#--------------------------------------------------------------------------------
#
#--------------------------------------------------------------------------------
main()
Therefore, we would like to know the meaning of the error, not the direct cause of the error.
For example, which program in Enzyme.jl is causing the following error? and so on.
Also, if I knew what “addrspace(10)*” etc. meant, I might be able to modify the program myself.
So from the error message preprocess_julia_setup_12036_inner probably means that this is happening for a function called “setup” or something similar.
This is an Enzyme internal error message that something has gone wrong with finding the derivative variable for a given variable in the original function. I’m not sure what I could provide without some more context of the program that causes it to err.
The {} addrspace(10)* type is how Julia represents GC-managed objects.