Mantid
Loading...
Searching...
No Matches
WrapWithNDArray.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//-----------------------------------------------------------------------------
8// Includes
9//-----------------------------------------------------------------------------
12#include "MantidPythonInterface/core/DllConfig.h"
13
14#include <boost/python/list.hpp>
15#define PY_ARRAY_UNIQUE_SYMBOL CORE_ARRAY_API
16#define NO_IMPORT_ARRAY
17#include <numpy/arrayobject.h>
18
19#include <string>
20
21namespace {
22
28template <typename T> void capsule_cleanup(PyObject *capsule) {
29 auto *memory = static_cast<T *>(PyCapsule_GetPointer(capsule, NULL));
30 delete[] memory;
31}
32
33} // namespace
34
36#ifdef __APPLE__
37extern template int NDArrayTypeIndex<bool>::typenum;
38extern template int NDArrayTypeIndex<int>::typenum;
39extern template int NDArrayTypeIndex<long>::typenum;
40extern template int NDArrayTypeIndex<long long>::typenum;
44extern template int NDArrayTypeIndex<float>::typenum;
45extern template int NDArrayTypeIndex<double>::typenum;
46#endif
47
48namespace {
55void markReadOnly(PyArrayObject *arr) {
56#if NPY_API_VERSION >= 0x00000007 //(1.7)
57 PyArray_CLEARFLAGS(arr, NPY_ARRAY_WRITEABLE);
58#else
59 arr->flags &= ~NPY_WRITEABLE;
60#endif
61}
62} // namespace
63
64namespace Impl {
65
79template <typename ElementType>
80PyObject *wrapWithNDArray(const ElementType *carray, const int ndims, Py_intptr_t *dims, const NumpyWrapMode mode,
81 const OwnershipMode oMode /* = Cpp */) {
83 auto *nparray = reinterpret_cast<PyArrayObject *>(
84 PyArray_SimpleNewFromData(ndims, dims, datatype, static_cast<void *>(const_cast<ElementType *>(carray))));
85
86 if (oMode == Python) {
87 PyObject *capsule = PyCapsule_New(const_cast<ElementType *>(carray), NULL, capsule_cleanup<ElementType>);
88 PyArray_SetBaseObject(reinterpret_cast<PyArrayObject *>(nparray), capsule);
89 }
90
91 if (mode == ReadOnly)
92 markReadOnly(nparray);
93 return reinterpret_cast<PyObject *>(nparray);
94}
95
96//-----------------------------------------------------------------------
97// Explicit instantiations
98//-----------------------------------------------------------------------
99#define INSTANTIATE_WRAPNUMPY(ElementType) \
100 template MANTID_PYTHONINTERFACE_CORE_DLL PyObject *wrapWithNDArray<ElementType>( \
101 const ElementType *, const int ndims, Py_intptr_t *dims, const NumpyWrapMode mode, const OwnershipMode oMode);
102
106INSTANTIATE_WRAPNUMPY(long long)
107INSTANTIATE_WRAPNUMPY(unsigned int)
108INSTANTIATE_WRAPNUMPY(unsigned long)
109INSTANTIATE_WRAPNUMPY(unsigned long long)
113} // namespace Impl
114} // namespace Mantid::PythonInterface::Converters
tagPyArrayObject PyArrayObject
#define INSTANTIATE_WRAPNUMPY(ElementType)
PyObject * wrapWithNDArray(const ElementType *, const int ndims, Py_intptr_t *dims, const NumpyWrapMode mode, const OwnershipMode oMode=OwnershipMode::Cpp)
Defines the wrapWithNDArray specialization for C array types.
NumpyWrapMode
Enum defining wrapping type for conversion to numpy.
OwnershipMode
Enum defining transfer of ownership when converting to numpy array.
Defines a mapping between C++ type given by the template parameter and numpy type enum NPY_TYPES.