Convert torch tensor in julia type with PyCall.jl

Hi everybody,
It’s my first time that I use PyCall and I have a problem that I could not manage to solve.
I’m using julia to simulate biological neural networks and I’m trying to use a program written in python (that uses intensively pytorch) to find the best parameters.
My simulator is wrapped in a function that is passed to the python function “infer” as a parameter, this function take the input parameters from a distribution and pass a tensor array to my julia function.
My problem is that I cannot convert this PyObject in a julia type, I tried different ways but the type remain always a PyObject tensor.
My code is something like this:

Using Mymodule
Using PyCall

function simulator(parameters)
    reults = Mymodule.sim(parameters)
    return results
end

py"""
import pyModule
prior_min = [1, 1]
prior_max = [10,10]
prior = utils.torchutils.BoxUniform(low=torch.as_tensor(prior_min), 
                                        high=torch.as_tensor(prior_max))
posterior = pyModule.infer($simulator, prior)
"""

This is my very long error

ERROR: (in a Julia function called from Python)
JULIA: TypeError: in keyword argument p, expected Real, got a value of type PyCall.PyObject
Stacktrace:
  [1] simulator(par::PyCall.PyObject)
    @ Main.sbi C:\Users\fec45kv\.julia\dev\Enthusiast\sim\sbigo.jl:27
  [2] invokelatest(::Any, ::Any, ::Vararg{Any, N} where N; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Base .\essentials.jl:708
  [3] invokelatest(::Any, ::Any, ::Vararg{Any, N} where N)
    @ Base .\essentials.jl:706
  [4] _pyjlwrap_call(f::Function, args_::Ptr{PyCall.PyObject_struct}, kw_::Ptr{PyCall.PyObject_struct})
    @ PyCall C:\Users\fec45kv\.julia\packages\PyCall\7a7w0\src\callback.jl:28
  [5] pyjlwrap_call(self_::Ptr{PyCall.PyObject_struct}, args_::Ptr{PyCall.PyObject_struct}, kw_::Ptr{PyCall.PyObject_struct})
    @ PyCall C:\Users\fec45kv\.julia\packages\PyCall\7a7w0\src\callback.jl:44
  [6] macro expansion
    @ C:\Users\fec45kv\.julia\packages\PyCall\7a7w0\src\exception.jl:95 [inlined]
  [7] #117
    @ C:\Users\fec45kv\.julia\packages\PyCall\7a7w0\src\pyeval.jl:38 [inlined]
  [8] disable_sigint(f::PyCall.var"#117#118"{PyCall.PyDict{String, PyCall.PyObject, true}, PyCall.PyDict{String, PyCall.PyObject, true}, PyCall.PyObject})
    @ Base .\c.jl:458
  [9] invokelatest(::Any, ::Any, ::Vararg{Any, N} where N; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Base .\essentials.jl:708
 [10] invokelatest(::Any, ::Any, ::Vararg{Any, N} where N)
    @ Base .\essentials.jl:706
 [11] evaluate_call_recurse!(recurse::Any, frame::JuliaInterpreter.Frame, call_expr::Expr; enter_generated::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:255
 [12] evaluate_call_recurse!(recurse::Any, frame::JuliaInterpreter.Frame, call_expr::Expr)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:227
 [13] eval_rhs(recurse::Any, frame::JuliaInterpreter.Frame, node::Expr)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:391
 [14] step_expr!(recurse::Any, frame::JuliaInterpreter.Frame, node::Any, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:465
 [15] step_expr!
    @ C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:594 [inlined]
 [16] finish!(recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:14
 [17] finish_and_return!
    @ C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:30 [inlined]
 [18] evaluate_call_recurse!(recurse::Any, frame::JuliaInterpreter.Frame, call_expr::Expr; enter_generated::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:266
 [19] evaluate_call_recurse!(recurse::Any, frame::JuliaInterpreter.Frame, call_expr::Expr)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:227
 [20] eval_rhs(recurse::Any, frame::JuliaInterpreter.Frame, node::Expr)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:391
 [21] step_expr!(recurse::Any, frame::JuliaInterpreter.Frame, node::Any, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:539
 [22] step_expr!
    @ C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:594 [inlined]
 [23] next_until!(predicate::Any, recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:92
 [24] _next_line!(recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool, initialline::Int64, initialfile::String)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:181
 [25] next_line!(recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:176
 [26] debug_command(recurse::Any, frame::JuliaInterpreter.Frame, cmd::Symbol, rootistoplevel::Bool; line::Nothing)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:457
 [27] debug_command(recurse::Any, frame::JuliaInterpreter.Frame, cmd::Symbol, rootistoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:439
 [28] (::Atom.JunoDebugger.var"#54#56"{Bool, Bool, Bool})()
    @ Atom.JunoDebugger C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:199
 [29] evalscope(f::Atom.JunoDebugger.var"#54#56"{Bool, Bool, Bool})
    @ Atom.JunoDebugger C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:392
 [30] startdebugging(frame::JuliaInterpreter.Frame, initial_continue::Bool; istoplevel::Bool, toggle_ui::Bool)
    @ Atom.JunoDebugger C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:157
 [31] startdebugging(frame::JuliaInterpreter.Frame, initial_continue::Bool)
    @ Atom.JunoDebugger C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:143
 [32] top-level scope
    @ C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:50
 [33] eval
    @ .\boot.jl:360 [inlined]
 [34] repleval(mod::Module, line::Expr)
    @ Atom C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\repl.jl:198
 [35] (::Atom.var"#242#244"{Module})()
    @ Atom C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\repl.jl:228
 [36] with_logstate(f::Function, logstate::Any)
    @ Base.CoreLogging .\logging.jl:491
 [37] with_logger
    @ .\logging.jl:603 [inlined]
 [38] evalrepl(mod::Module, line::String)
    @ Atom C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\repl.jl:216
 [39] top-level scope
    @ C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\repl.jl:264
 [40] eval
    @ .\boot.jl:360 [inlined]
 [41] eval_user_input(ast::Any, backend::REPL.REPLBackend)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:139
 [42] repl_backend_loop(backend::REPL.REPLBackend)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:200
 [43] start_repl_backend(backend::REPL.REPLBackend, consumer::Any)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:185
 [44] run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:317
 [45] run_repl(repl::REPL.AbstractREPL, consumer::Any)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:305
 [46] (::Base.var"#874#876"{Bool, Bool, Bool})(REPL::Module)
    @ Base .\client.jl:387
 [47] #invokelatest#2
    @ .\essentials.jl:708 [inlined]
 [48] invokelatest
    @ .\essentials.jl:706 [inlined]
 [49] run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool)
    @ Base .\client.jl:372
 [50] exec_options(opts::Base.JLOptions)
    @ Base .\client.jl:302
Stacktrace:
  [1] pyerr_check
    @ C:\Users\fec45kv\.julia\packages\PyCall\7a7w0\src\exception.jl:62 [inlined]
  [2] pyerr_check
    @ C:\Users\fec45kv\.julia\packages\PyCall\7a7w0\src\exception.jl:66 [inlined]
  [3] _handle_error(msg::String)
    @ PyCall C:\Users\fec45kv\.julia\packages\PyCall\7a7w0\src\exception.jl:83
  [4] macro expansion
    @ C:\Users\fec45kv\.julia\packages\PyCall\7a7w0\src\exception.jl:97 [inlined]
  [5] #117
    @ C:\Users\fec45kv\.julia\packages\PyCall\7a7w0\src\pyeval.jl:38 [inlined]
  [6] disable_sigint(f::PyCall.var"#117#118"{PyCall.PyDict{String, PyCall.PyObject, true}, PyCall.PyDict{String, PyCall.PyObject, true}, PyCall.PyObject})
    @ Base .\c.jl:458
  [7] invokelatest(::Any, ::Any, ::Vararg{Any, N} where N; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Base .\essentials.jl:708
  [8] invokelatest(::Any, ::Any, ::Vararg{Any, N} where N)
    @ Base .\essentials.jl:706
  [9] evaluate_call_recurse!(recurse::Any, frame::JuliaInterpreter.Frame, call_expr::Expr; enter_generated::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:255
 [10] evaluate_call_recurse!(recurse::Any, frame::JuliaInterpreter.Frame, call_expr::Expr)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:227
 [11] eval_rhs(recurse::Any, frame::JuliaInterpreter.Frame, node::Expr)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:391
 [12] step_expr!(recurse::Any, frame::JuliaInterpreter.Frame, node::Any, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:465
 [13] step_expr!
    @ C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:594 [inlined]
 [14] finish!(recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:14
 [15] finish_and_return!
    @ C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:30 [inlined]
 [16] evaluate_call_recurse!(recurse::Any, frame::JuliaInterpreter.Frame, call_expr::Expr; enter_generated::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:266
 [17] evaluate_call_recurse!(recurse::Any, frame::JuliaInterpreter.Frame, call_expr::Expr)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:227
 [18] eval_rhs(recurse::Any, frame::JuliaInterpreter.Frame, node::Expr)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:391
 [19] step_expr!(recurse::Any, frame::JuliaInterpreter.Frame, node::Any, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:539
 [20] step_expr!
    @ C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\interpret.jl:594 [inlined]
 [21] next_until!(predicate::Any, recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:92
 [22] _next_line!(recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool, initialline::Int64, initialfile::String)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:181
 [23] next_line!(recurse::Any, frame::JuliaInterpreter.Frame, istoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:176
 [24] debug_command(recurse::Any, frame::JuliaInterpreter.Frame, cmd::Symbol, rootistoplevel::Bool; line::Nothing)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:457
 [25] debug_command(recurse::Any, frame::JuliaInterpreter.Frame, cmd::Symbol, rootistoplevel::Bool)
    @ JuliaInterpreter C:\Users\fec45kv\.julia\packages\JuliaInterpreter\7spiM\src\commands.jl:439
 [26] (::Atom.JunoDebugger.var"#54#56"{Bool, Bool, Bool})()
    @ Atom.JunoDebugger C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:199
 [27] evalscope(f::Atom.JunoDebugger.var"#54#56"{Bool, Bool, Bool})
    @ Atom.JunoDebugger C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:392
 [28] startdebugging(frame::JuliaInterpreter.Frame, initial_continue::Bool; istoplevel::Bool, toggle_ui::Bool)
    @ Atom.JunoDebugger C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:157
 [29] startdebugging(frame::JuliaInterpreter.Frame, initial_continue::Bool)
    @ Atom.JunoDebugger C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:143
 [30] top-level scope
    @ C:\Users\fec45kv\.julia\packages\Atom\BUIFZ\src\debugger\stepper.jl:50

Thanks in advance for the help. I really love julia and its community. This is the first time that I post something because I usually find everything in this forum

1 Like

Try GitHub - rejuvyesh/PyCallChainRules.jl: Differentiate python calls from Julia or GitHub - pabloferz/DLPack.jl: Julia interface for dlpack

1 Like

Thanks :pray:, DLPack works perfectly.
Just for clarity I attach the code to solve the problem.

using Mymodule
using PyCall
using DLPack
torch = pyimport("torch")

function simulator(parameters)
    julia_parameters = DLPack.wrap(parameters, o -> @pycall torch.to_dlpack(o)::PyObject)
    reults = Mymodule.sim(julia_parameters)
    return results
end

py"""
import pyModule
torch = $torch
prior_min = [1, 1]
prior_max = [10,10]
prior = utils.torchutils.BoxUniform(low=torch.as_tensor(prior_min), 
                                        high=torch.as_tensor(prior_max))
posterior = pyModule.infer($simulator, prior)
"""
1 Like