Skip to content

Commit

Permalink
Move py fun wrapper to type_conv from libpymcr main
Browse files Browse the repository at this point in the history
  • Loading branch information
mducle committed Sep 23, 2023
1 parent 7767cb9 commit d8ed104
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 25 deletions.
9 changes: 6 additions & 3 deletions libpymcr/MatlabProxyObject.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ def __init__(self, interface, handle):
"""
self.__dict__['handle'] = handle
self.__dict__['interface'] = interface
self.__dict__['_is_handle_class'] = self.interface.call('isa', self.handle, 'handle', nargout=1)
self.__dict__['_methods'] = []
#self.__dict__['_is_handle_class'] = self.interface.call('isa', self.handle, 'handle', nargout=1)

# This cause performance slow downs for large data members and an recursion issue with
# samples included in sqw object (each sample object is copied to all dependent header "files")
Expand All @@ -96,7 +97,9 @@ def _getMethodNames(self):
Gets methods from a MATLAB object
:return: list of method names
"""
return self.interface.call('methods', self.handle)
if not self._methods:
self.__dict__['_methods'] = self.interface.call('methods', self.handle)
return self._methods

def __getattr__(self, name):
"""Retrieve a value or function from the object.
Expand All @@ -115,7 +118,7 @@ def __getattr__(self, name):
except TypeError:
return None
# if it's a method, wrap it in a functor
elif name in self.interface.call('methods', self.handle, nargout=1):
elif name in self._methods:
return matlab_method(self, name)

def __setattr__(self, name, value):
Expand Down
2 changes: 1 addition & 1 deletion libpymcr/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def get_branch_of_call(astobj, parent=[]):
if rv:
parent.append(astobj)
return parent
return False
raise SyntaxError('Empty syntax tree')

def get_nret_from_call(caller):
if isinstance(caller, ast.Call):
Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ target_include_directories(call_python PUBLIC ${PYTHON_INCLUDE_DIRS})
target_include_directories(call_python PUBLIC "${pybind11_SOURCE_DIR}/include")
##target_link_libraries(call_python type_converter)
## Explicitly does not link with Matlab libraries (we will call them with dlopen etc)
#set_property(TARGET call_python PROPERTY LINK_LIBRARIES "")
set_property(TARGET call_python PROPERTY LINK_LIBRARIES "")
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_link_libraries(call_python ${PYTHON_LIBRARIES})
endif()
Expand Down
17 changes: 2 additions & 15 deletions src/libpymcr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,21 @@

namespace libpymcr {

matlab::data::Array matlab_env::_conv_to_matlab(PyObject* input) {
matlab::data::Array rv;
if (PyCallable_Check(input)) {
matlab::data::ArrayFactory factory;
std::uintptr_t addr = reinterpret_cast<std::uintptr_t>(input);
rv = factory.createStructArray({1, 1}, std::vector<std::string>({"libpymcr_func_ptr"}));
rv[0][std::string("libpymcr_func_ptr")] = factory.createScalar<uint64_t>(addr);
} else {
rv = _converter.to_matlab(input);
}
return rv;
}

size_t matlab_env::_parse_inputs(std::vector<matlab::data::Array>& m_args,
py::args py_args,
py::kwargs& py_kwargs) {
matlab::data::ArrayFactory factory;
size_t nargout = 1;
for (auto item: py_args) {
m_args.push_back(_conv_to_matlab(item.ptr()));
m_args.push_back(_converter.to_matlab(item.ptr()));
}
for (auto item: py_kwargs) {
std::string key(py::str(item.first));
if (key.find("nargout") == 0) {
nargout = item.second.cast<size_t>();
} else {
m_args.push_back(factory.createCharArray(std::string(py::str(item.first))));
m_args.push_back(_conv_to_matlab(item.second.ptr()));
m_args.push_back(_converter.to_matlab(item.second.ptr()));
}
}
return nargout;
Expand Down
1 change: 0 additions & 1 deletion src/libpymcr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ namespace libpymcr {
std::shared_ptr<StreamBuffer> _m_output_buf = std::static_pointer_cast<StreamBuffer>(_m_output);
std::shared_ptr<StreamBuffer> _m_error_buf = std::static_pointer_cast<StreamBuffer>(_m_error);
pymat_converter _converter;
matlab::data::Array _conv_to_matlab(PyObject* input);
size_t _parse_inputs(std::vector<matlab::data::Array>& m_args, py::args py_args, py::kwargs& py_kwargs);
public:
py::object feval(const std::u16string &funcname, py::args args, py::kwargs& kwargs);
Expand Down
10 changes: 7 additions & 3 deletions src/type_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,9 +519,13 @@ Array pymat_converter::listtuple_to_cell(PyObject *result, matlab::data::ArrayFa
}
}

matlab::data::Array pymat_converter::wrap_python_function(PyObject *input) {
matlab::data::Array pymat_converter::wrap_python_function(PyObject *input, matlab::data::ArrayFactory &factory) {
// Wraps a Python function so it can be called using a mex function
throw std::runtime_error("Python callable conversion requires a custom entry point and mex file");
matlab::data::Array rv;
std::uintptr_t addr = reinterpret_cast<std::uintptr_t>(input);
rv = factory.createStructArray({1, 1}, std::vector<std::string>({"libpymcr_func_ptr"}));
rv[0][std::string("libpymcr_func_ptr")] = factory.createScalar<uint64_t>(addr);
return rv;
}

matlab::data::Array pymat_converter::python_to_matlab_single(PyObject *input, matlab::data::ArrayFactory &factory) {
Expand All @@ -548,7 +552,7 @@ matlab::data::Array pymat_converter::python_to_matlab_single(PyObject *input, ma
} else if (input == Py_None) {
output = factory.createArray<double>({});
} else if (PyCallable_Check(input)) {
output = wrap_python_function(input);
output = wrap_python_function(input, factory);
} else if (PyObject_TypeCheck(input, m_py_matlab_wrapper_t)) {
output = mArray(reinterpret_cast<matlab_wrapper*>(input)->arr_impl_sptr);
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/type_converter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ namespace libpymcr {
CharArray python_string_to_matlab(PyObject *result, matlab::data::ArrayFactory &factory);
Array listtuple_to_cell(PyObject *result, matlab::data::ArrayFactory &factory);
StructArray python_dict_to_matlab(PyObject *result, matlab::data::ArrayFactory &factory);
matlab::data::Array wrap_python_function(PyObject *input);
matlab::data::Array wrap_python_function(PyObject *input, matlab::data::ArrayFactory &factory);
matlab::data::Array python_to_matlab_single(PyObject *input, matlab::data::ArrayFactory &factory);
public:
void clear_py_cache();
Expand Down

0 comments on commit d8ed104

Please sign in to comment.