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

Make Python bindings thread-friendly #2442

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions swig/casadi.i
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@
%}
%init %{
// Set logger functions
casadi::Logger::writeFun = casadi::pythonlogger;
// Disabled as pythonlogger takes the GIL
// casadi::Logger::writeFun = casadi::pythonlogger;

// @jgillis: please document
casadi::InterruptHandler::checkInterrupted = casadi::pythoncheckinterrupted;
Expand Down Expand Up @@ -3951,14 +3952,42 @@ def PyFunction(name, obj, inputs, outputs, opts={}):
#ifdef SWIGPYTHON
namespace casadi{
%extend Function {
void call_without_gil_if_dm(const std::vector<DM> &arg, std::vector<DM>& SWIG_OUTPUT(res),
bool always_inline=false, bool never_inline=false) const {
Py_BEGIN_ALLOW_THREADS
self->call(arg, SWIG_OUTPUT(res), always_inline, never_inline);
Py_END_ALLOW_THREADS
};
void call_without_gil_if_dm(const std::vector<SX> &arg, std::vector<SX>& SWIG_OUTPUT(res),
bool always_inline=false, bool never_inline=false) const {
self->call(arg, SWIG_OUTPUT(res), always_inline, never_inline);
};
void call_without_gil_if_dm(const std::vector<MX> &arg, std::vector<MX>& SWIG_OUTPUT(res),
bool always_inline=false, bool never_inline=false) const {
self->call(arg, SWIG_OUTPUT(res), always_inline, never_inline);
};
void call_without_gil_if_dm(const DMDict& arg, DMDict& SWIG_OUTPUT(res),
bool always_inline=false, bool never_inline=false) const {
Py_BEGIN_ALLOW_THREADS
self->call(arg, SWIG_OUTPUT(res), always_inline, never_inline);
Py_END_ALLOW_THREADS
};
void call_without_gil_if_dm(const SXDict& arg, SXDict& SWIG_OUTPUT(res),
bool always_inline=false, bool never_inline=false) const {
self->call(arg, SWIG_OUTPUT(res), always_inline, never_inline);
};
void call_without_gil_if_dm(const MXDict& arg, MXDict& SWIG_OUTPUT(res),
bool always_inline=false, bool never_inline=false) const {
self->call(arg, SWIG_OUTPUT(res), always_inline, never_inline);
};
%pythoncode %{
def __call__(self, *args, **kwargs):
# Either named inputs or ordered inputs
if len(args)>0 and len(kwargs)>0:
raise SyntaxError('Function evaluation requires all arguments to be named or none')
if len(args)>0:
# Ordered inputs -> return tuple
ret = self.call(args)
ret = self.call_without_gil_if_dm(args)
if len(ret)==0:
return None
elif len(ret)==1:
Expand All @@ -3967,7 +3996,7 @@ namespace casadi{
return tuple(ret)
else:
# Named inputs -> return dictionary
return self.call(kwargs)
return self.call_without_gil_if_dm(kwargs)
%}
}
}
Expand Down