Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backpropagation fails with "No matching function wrapper was found!" even when gradcheck succeeds #10

Open
LilithHafner opened this issue Oct 30, 2023 · 3 comments

Comments

@LilithHafner
Copy link
Member

LilithHafner commented Oct 30, 2023

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?

@LilithHafner
Copy link
Member Author

Using ODEProblem{true, SciMLBase.FullSpecialize} instead of ODEProblem works, but I'm still concerned because this error is not very user-friendly.

@ChrisRackauckas
Copy link
Member

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

@oscardssmith
Copy link

oscardssmith commented Nov 2, 2023

fyi: your mwe is slightly wrong. It should be jl('Pkg.add(["DifferentialEquations"])')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants