TRIQS/nda
2.0.0
Multi-dimensional array library for C++
Toggle main menu visibility
Loading...
Searching...
No Matches
make_py_capsule.hpp
1
// Copyright (c) 2018--present, The Simons Foundation
2
// This file is part of TRIQS/nda and is licensed under the Apache License, Version 2.0.
3
// SPDX-License-Identifier: Apache-2.0
4
// See LICENSE in the root of this distribution for details.
5
6
#pragma once
7
8
// SHOULD ONLY BE INCLUDED in a python module.
9
10
#include <Python.h>
11
#include <numpy/arrayobject.h>
12
#include <
nda/nda.hpp
>
13
14
namespace
nda::python {
15
16
// ------------- make_handle ------------
17
19
static
inline
void
py_decref(
void
*x) { Py_DECREF((PyObject *)x); }
20
21
// Take a handle on a numpy. numpy is a borrowed Python ref.
22
// implemented only in Python module, not in triqs cpp
23
template
<
typename
T>
24
nda::mem::handle_shared<T> make_handle(PyObject *obj) {
25
26
if
(obj == NULL)
throw
std::runtime_error(
" Can not build an mem_blk_handle from a NULL PyObject *"
);
27
if
(!PyArray_Check(obj))
throw
std::runtime_error(
"Internal error : ref_counter construct from pyo : obj is not an array"
);
28
29
// We create a new shared handle -> increase refcount
30
Py_INCREF(obj);
31
32
PyArrayObject *arr = (PyArrayObject *)(obj);
33
34
nda::mem::handle_shared<T> r{
35
(T *)PyArray_DATA(arr),
// data
36
size_t(PyArray_SIZE(arr)),
// size
37
obj,
// foreign_handle
38
(
void
*)&py_decref
// foreign_decref
39
};
40
return
r;
41
}
42
43
// ------------------ delete_pycapsule ----------------------------------------------------
44
45
// Properly delete the nda::mem::handle_shared<T> in a PyCapsule
46
template
<
typename
T>
47
static
void
delete_pycapsule(PyObject *capsule) {
48
nda::mem::handle_shared<T> *handle =
static_cast<
nda::mem::handle_shared<T> *
>
(PyCapsule_GetPointer(capsule,
"guard"
));
49
//std::cerr << "decapsulate : "<< handle->id << " "<< handle->data << " nrefs" << handle->nref() << "\n";
50
delete
handle;
51
}
52
53
// ------------------ make_pycapsule, ----------------------------------------------------
54
55
// Make a pycapsule out of the shared handle to return to Python
56
template
<
typename
T>
57
PyObject *make_pycapsule(nda::mem::handle_heap<T>
const
&h) {
58
void
*keep =
new
nda::mem::handle_shared<T>{h};
// a new reference
59
return
PyCapsule_New(keep,
"guard"
, &delete_pycapsule<T>);
60
}
61
62
template
<
typename
T>
63
PyObject *make_pycapsule(nda::mem::handle_borrowed<T>
const
&h) {
64
using
U = std::remove_const_t<T>;
65
if
(h.
parent
() ==
nullptr
)
throw
std::runtime_error(
"Can not return to python a view on something else than an nda::array"
);
66
void
*keep =
new
nda::mem::handle_shared<U>{*h.
parent
()};
// a new reference
67
return
PyCapsule_New(keep,
"guard"
, &delete_pycapsule<T>);
68
}
69
70
}
// namespace nda::python
nda.hpp
Includes all relevant headers for the core nda library.
nda::mem::handle_borrowed::parent
handle_heap< T0 > const * parent() const
Get a pointer to the parent handle.
Definition
handle.hpp:921
nda
c2py
make_py_capsule.hpp
Generated by
1.17.0