Backpropagation fails with "No matching function wrapper was found!" even when gradcheck succeeds
LilithHafner opened this issue · 3 comments
I defined a simple ODE and attempted to tune parameters and initial conditions to match simulated observations. However, I got a "No matching function wrapper was found!" error.
from juliatorch import JuliaFunction
import juliacall, torch
jl = juliacall.Main.seval
jl('import Pkg')
jl('Pkg.add(["DifferentialEquations"])')
jl('using DifferentialEquations')
make_f = jl("""ode_f -> function (inp)
x0, v0, p = inp
tspan = (0.0, 1.0)
prob = ODEProblem(ode_f, [x0, v0], tspan, p)
sol = DifferentialEquations.solve(prob)
# return sol.u[end]
hcat(sol(.5), sol(1.0))
end""")
def py_ode_f(du, u, p, t):
x = u[0]
v = u[1]
dx = v
dv = -p * x
du[0] = dx
du[1] = dv
# return [dx, dv]
f = make_f(py_ode_f)
print(f([1, 2, 3]))
# [1.5274653930969104 0.9791625277649281; -0.023690980408490492 -2.0306945154435274]
x = torch.randn(3, dtype=torch.double, requires_grad=True)
print(JuliaFunction.apply(f, x))
# tensor([[-0.4471, -0.3979],
# [ 0.3155, -0.1103]], dtype=torch.float64,
# grad_fn=<JuliaFunctionBackward>)
from torch.autograd import gradcheck
py_f = lambda x: f(x)
print(gradcheck(JuliaFunction.apply, (py_f, x), eps=1e-6, atol=1e-4))
# True
parameters = torch.tensor([1.0, 1.0, 1.0], requires_grad=True)
observations = torch.randn(2,2)
weights = torch.tensor([[1.0, 0.0], [0.0, 0.0]])
n_steps = 1000
learning_rate = 1e-2
optimizer = torch.optim.SGD([parameters], lr=learning_rate)
for i in range(n_steps):
optimizer.zero_grad()
solution = JuliaFunction.apply(py_f, parameters)
loss = torch.sum(weights * torch.abs(solution - observations)) # Define the loss function
loss.backward() # This line errors
optimizer.step() # Update parameters
I tried to use SciMLBase.unwrapped_f
by changing ODEProblem(ode_f, [x0, v0], tspan, p)
to ODEProblem(SciMLBase.unwrapped_f(ode_f), [x0, v0], tspan, p)
, but this did not change the error.
The full error message is very long because of large types. I had to abridge it to stay within Github's post length limits
Traceback (most recent call last):
File "<stdin>", line 5, in <module>
File "/opt/homebrew/lib/python3.11/site-packages/torch/_tensor.py", line 492, in backward
torch.autograd.backward(
File "/opt/homebrew/lib/python3.11/site-packages/torch/autograd/__init__.py", line 251, in backward
Variable._execution_engine.run_backward( # Calls into the C++ engine to run the backward pass
File "/opt/homebrew/lib/python3.11/site-packages/torch/autograd/function.py", line 288, in apply
return user_fn(self, *args)
^^^^^^^^^^^^^^^^^^^^
File "/opt/homebrew/lib/python3.11/site-packages/juliatorch/__init__.py", line 37, in backward
jl_grad = gradient(ls, np_x)
^^^^^^^^^^^^^^^^^^
File "/Users/x/.julia/packages/PythonCall/qTEA1/src/jlwrap/any.jl", line 208, in __call__
return self._jl_callmethod($(pyjl_methodnum(pyjlany_call)), args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<stdin>", line 1, in <lambda>
File "/Users/x/.julia/packages/PythonCall/qTEA1/src/jlwrap/any.jl", line 208, in __call__
return self._jl_callmethod($(pyjl_methodnum(pyjlany_call)), args, kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
juliacall.JuliaError: No matching function wrapper was found!
Stacktrace:
[1] _call(#unused#::Tuple{}, arg::Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, Float64}, fww::FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py,
[...]
aryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, args::CompositeAlgorithm{Tuple{Vern7{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, Rodas5P{1, false, LinearSolve.DefaultLinearSolver, typeof(OrdinaryDiffEq.DEFAULT_PRECS), Val{:forward}, true, nothing}}, AutoSwitch{Vern7{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, Rodas5P{0, false, Nothing, typeof(OrdinaryDiffEq.DEFAULT_PRECS), Val{:forward}, true, nothing}, Rational{Int64}, Int64}}; merge_callbacks::Bool, kwargshandle::Nothing, kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol, Symbol}, NamedTuple{(:default_set, :second_time), Tuple{Bool, Bool}}})
@ DiffEqBase ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:557
[16] solve_call
@ ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:523 [inlined]
[17] #solve_up#42
@ ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:1006 [inlined]
[18] solve_up
@ ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:992 [inlined]
[19] #solve#40
@ ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:929 [inlined]
[20] __solve(::ODEProblem{Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, Tuple{Float64, Float64}, true, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}, ::Nothing; default_set::Bool, kwargs::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:second_time,), Tuple{Bool}}})
@ DifferentialEquations ~/.julia/packages/DifferentialEquations/Tu7HS/src/default_solve.jl:14
[21] __solve
@ ~/.julia/packages/DifferentialEquations/Tu7HS/src/default_solve.jl:1 [inlined]
[22] #__solve#63
@ ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:1285 [inlined]
[23] __solve
@ ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:1278 [inlined]
[24] #solve_call#34
@ ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:557 [inlined]
[25] solve_call(::ODEProblem{Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, Tuple{Float64, Float64}, true, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, 1}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}}, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float64, 3}, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem})
@ DiffEqBase ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:523
[26] #solve_up#42
@ ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:998 [inlined]
[27] solve_up
@ ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:992 [inlined]
[28] solve(::ODEProblem{Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, Tuple{Float64, Float64}, true, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ODEFunction{true, SciMLBase.AutoSpecialize, ComposedFunction{typeof(SciMLBasePythonCallExt._pyconvert), Py}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem}; sensealg::Nothing, u0::Nothing, p::Nothing, wrap::Val{true}, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ DiffEqBase ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:929
[29] solve(::ODEProblem{Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}, Tuple{Float64, Float64}, true, ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}, ODEFunction{true, SciMLBase.AutoSpecialize, ComposedFunction{typeof(SciMLBasePythonCallExt._pyconvert), Py}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, SciMLBase.StandardODEProblem})
@ DiffEqBase ~/.julia/packages/DiffEqBase/5eEQ1/src/solve.jl:919
[30] (::var"#46#48"{Py})(inp::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}})
@ Main ./none:5
[31] pyjlany_call(self::var"#46#48"{Py}, args_::Py, kwargs_::Py)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/jlwrap/any.jl:37
[32] _pyjl_callmethod(f::Any, self_::Ptr{PythonCall.C.PyObject}, args_::Ptr{PythonCall.C.PyObject}, nargs::Int64)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/jlwrap/base.jl:69
[33] _pyjl_callmethod(o::Ptr{PythonCall.C.PyObject}, args::Ptr{PythonCall.C.PyObject})
@ PythonCall.C ~/.julia/packages/PythonCall/qTEA1/src/cpython/jlwrap.jl:47
[34] PyObject_CallObject
@ ~/.julia/packages/PythonCall/qTEA1/src/cpython/pointers.jl:299 [inlined]
[35] macro expansion
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:131 [inlined]
[36] pycallargs
@ ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:210 [inlined]
[37] pycall(f::Py, args::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:228
[38] pycall
@ ~/.julia/packages/PythonCall/qTEA1/src/abstract/object.jl:218 [inlined]
[39] #_#11
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[40] Py
@ ~/.julia/packages/PythonCall/qTEA1/src/Py.jl:341 [inlined]
[41] (::var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}})(x::Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}})
@ Main ./none:1
[42] vector_mode_dual_eval!
@ ~/.julia/packages/ForwardDiff/PcZ48/src/apiutils.jl:24 [inlined]
[43] vector_mode_gradient(f::var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, x::PyArray{Float32, 1, true, true, Float32}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:89
[44] gradient(f::Function, x::PyArray{Float32, 1, true, true, Float32}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}}, ::Val{true})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:0
[45] gradient(f::Function, x::PyArray{Float32, 1, true, true, Float32}, cfg::ForwardDiff.GradientConfig{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3, Vector{ForwardDiff.Dual{ForwardDiff.Tag{var"#12#13"{Py, PyArray{Float64, 2, true, false, Float64}}, Float32}, Float32, 3}}})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:17
[46] gradient(f::Function, x::PyArray{Float32, 1, true, true, Float32})
@ ForwardDiff ~/.julia/packages/ForwardDiff/PcZ48/src/gradient.jl:17
[47] pyjlany_call(self::typeof(gradient), args_::Py, kwargs_::Py)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/jlwrap/any.jl:37
[48] _pyjl_callmethod(f::Any, self_::Ptr{PythonCall.C.PyObject}, args_::Ptr{PythonCall.C.PyObject}, nargs::Int64)
@ PythonCall ~/.julia/packages/PythonCall/qTEA1/src/jlwrap/base.jl:69
[49] _pyjl_callmethod(o::Ptr{PythonCall.C.PyObject}, args::Ptr{PythonCall.C.PyObject})
@ PythonCall.C ~/.julia/packages/PythonCall/qTEA1/src/cpython/jlwrap.jl:47
@ChrisRackauckas, do you know what may be causing this?
Using ODEProblem{true, SciMLBase.FullSpecialize}
instead of ODEProblem
works, but I'm still concerned because this error is not very user-friendly.
Copying from Slack discussion:
I see
, could the ODEFunction dispatch just check that f is a function from Python and choose to default to FullSpecialize based on that?
https://github.com/SciML/SciMLBase.jl/blob/master/src/problems/ode_problems.jl#L191C1-L192C1
I expect that would work, and perhaps it could be folded into the prepare_function function or a similar extensible API that can work for all problem types.
But I really have no idea what the error is or where it's coming from, and it's quite possible there is a more robust/extensible/appropriate solution (e.g. defining the appropriate function wrapper)
I expect that would work, and perhaps it could be folded into the prepare_function function or a similar extensible API that can work for all problem types.
Yes
fyi: your mwe is slightly wrong. It should be jl('Pkg.add(["DifferentialEquations"])')