31 PyErr_SetString(PyExc_RuntimeError,
"Object not convertible: Invalid Python object.");
37 if (pyinterface == NULL)
46 auto pyshape = PyDict_GetItemString(pyinterface,
"shape");
48 PyErr_SetString(PyExc_RuntimeError,
"Object not convertible: __array_interface__['shape'] does not exist.");
51 std::vector<std::size_t> shape;
52 for (
Py_ssize_t i = 0; i < PyTuple_Size(pyshape); i++) {
53 const auto s = PyLong_AsLong(PyTuple_GetItem(pyshape, i));
59 if (typestr.compare(
"") == 0)
65 const auto dtype = typestr.substr(1, typestr.size());
67 if (cppdtype.compare(
"") == 0)
71 if (!PyObject_HasAttrString(obj,
"strides")) {
72 PyErr_SetString(PyExc_RuntimeError,
"Object not convertible: Object does not have method 'strides'.");
75 auto pystrides = PyObject_GetAttrString(obj,
"strides");
76 std::vector<std::size_t> strides;
77 for (
Py_ssize_t i = 0; i < PyTuple_Size(pystrides); i++) {
78 strides.push_back(PyInt_AsLong(PyTuple_GetItem(pystrides, i)) / dtypesize);
84 if (strides.size() > 1) {
85 if (strides.front() < strides.back()) rowMajor =
false;
89 const std::string klassname =
"TMVA::Experimental::RTensor<" + cppdtype +
",std::vector<" + cppdtype +
">>";
90 std::stringstream code;
91 code <<
"new " << klassname <<
"(reinterpret_cast<" << cppdtype <<
"*>(" << data <<
"),{";
92 for (
auto s: shape) code << s <<
",";
94 for (
auto s: strides) code << s <<
",";
97 code <<
"TMVA::Experimental::MemoryLayout::RowMajor";
100 code <<
"TMVA::Experimental::MemoryLayout::ColumnMajor";
103 const auto codestr = code.str();
104 auto address = (
void*)
gInterpreter->Calc(codestr.c_str());
114 if (PyObject_SetAttrString(pyobj,
"__adopted__", obj)) {
115 PyErr_SetString(PyExc_RuntimeError,
"Object not convertible: Failed to set Python object as attribute __adopted__.");
120 Py_DECREF(pyinterface);
unsigned long long GetDataPointerFromArrayInterface(PyObject *obj)
Get data pointer from Numpy array interface and perform error handling.
unsigned int GetDatatypeSizeFromTypestr(const std::string &typestr)
Get size of data type in bytes from Numpy type string.
std::string GetCppTypeFromNumpyType(const std::string &dtype)
Convert Numpy data-type string to the according C++ data-type string.
std::string GetTypestrFromArrayInterface(PyObject *obj)
Get type string from Numpy array interface and perform error handling.
bool CheckEndianessFromTypestr(const std::string &typestr)
Check whether endianess in type string matches the endianess of ROOT.
PyObject * GetArrayInterface(PyObject *obj)
Get Numpy array interface and perform error handling.
PyObject * BindCppObject(Cppyy::TCppObject_t object, Cppyy::TCppType_t klass, const unsigned flags=0)
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
PyObject * AsRTensor(PyObject *self, PyObject *obj)
Adopt memory of a Python object with array interface using an RTensor.