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
13#include <boost/python/list.hpp>
14#define PY_ARRAY_UNIQUE_SYMBOL CORE_ARRAY_API
15#define NO_IMPORT_ARRAY
16#include <numpy/arrayobject.h>
17
18#include <string>
19
20namespace {
21
27template <typename T> void capsule_cleanup(PyObject *capsule) {
28 auto *memory = static_cast<T *>(PyCapsule_GetPointer(capsule, NULL));
29 delete[] memory;
30}
31
32} // namespace
33
35#ifdef __APPLE__
36extern template int NDArrayTypeIndex<bool>::typenum;
37extern template int NDArrayTypeIndex<int>::typenum;
38extern template int NDArrayTypeIndex<long>::typenum;
39extern template int NDArrayTypeIndex<long long>::typenum;
43extern template int NDArrayTypeIndex<float>::typenum;
44extern template int NDArrayTypeIndex<double>::typenum;
45#endif
46
47namespace {
54void markReadOnly(PyArrayObject *arr) {
55#if NPY_API_VERSION >= 0x00000007 //(1.7)
56 PyArray_CLEARFLAGS(arr, NPY_ARRAY_WRITEABLE);
57#else
58 arr->flags &= ~NPY_WRITEABLE;
59#endif
60}
61} // namespace
62
63namespace Impl {
64
78template <typename ElementType>
79PyObject *wrapWithNDArray(const ElementType *carray, const int ndims, Py_intptr_t *dims, const NumpyWrapMode mode,
80 const OwnershipMode oMode /* = Cpp */) {
82 auto *nparray = (PyArrayObject *)PyArray_SimpleNewFromData(ndims, dims, datatype,
83 static_cast<void *>(const_cast<ElementType *>(carray)));
84
85 if (oMode == Python) {
86 PyObject *capsule = PyCapsule_New(const_cast<ElementType *>(carray), NULL, capsule_cleanup<ElementType>);
87 PyArray_SetBaseObject((PyArrayObject *)nparray, capsule);
88 }
89
90 if (mode == ReadOnly)
91 markReadOnly(nparray);
92 return reinterpret_cast<PyObject *>(nparray);
93}
94
95//-----------------------------------------------------------------------
96// Explicit instantiations
97//-----------------------------------------------------------------------
98#define INSTANTIATE_WRAPNUMPY(ElementType) \
99 template DLLExport PyObject *wrapWithNDArray<ElementType>(const ElementType *, const int ndims, Py_intptr_t *dims, \
100 const NumpyWrapMode mode, const OwnershipMode oMode);
101
105INSTANTIATE_WRAPNUMPY(long long)
106INSTANTIATE_WRAPNUMPY(unsigned int)
107INSTANTIATE_WRAPNUMPY(unsigned long)
108INSTANTIATE_WRAPNUMPY(unsigned long long)
112} // namespace Impl
113} // 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.