@@ -71,12 +71,24 @@ vector<vector<py::array_t<cpx>>> fdct3d_forward_wrap(int nbscales, int nbangles_
71
71
c[i].resize (ctns[i].size ());
72
72
for (size_t j = 0 ; j < ctns[i].size (); j++)
73
73
{
74
+ // Create capsule linked to `ctns[i][j]._data` to track its lifetime
75
+ // https://stackoverflow.com/questions/44659924/returning-numpy-arrays-via-pybind11
76
+ py::capsule free_when_done (
77
+ ctns[i][j].data (),
78
+ [](void *cpx_ptr)
79
+ {
80
+ cpx *cpx_arr = reinterpret_cast <cpx *>(cpx_ptr);
81
+ delete[] cpx_arr;
82
+ });
83
+
74
84
py::array c_arr (
75
85
{ctns[i][j]._p , ctns[i][j]._n , ctns[i][j]._m }, // Shape
76
86
{sizeof (cpx) * ctns[i][j]._m * ctns[i][j]._n , // Strides (in bytes) of the underlying data array
77
87
sizeof (cpx) * ctns[i][j]._m ,
78
88
sizeof (cpx)},
79
- ctns[i][j].data ()); // Data pointer
89
+ ctns[i][j].data (), // Data pointer
90
+ free_when_done);
91
+
80
92
c[i][j] = c_arr;
81
93
ctns[i][j]._m = ctns[i][j]._n = ctns[i][j]._p = 0 ;
82
94
ctns[i][j]._data = NULL ;
@@ -127,12 +139,21 @@ py::array_t<cpx> fdct3d_inverse_wrap(int m, int n, int p, int nbscales, int nban
127
139
ctns[i][j]._data = NULL ;
128
140
}
129
141
142
+ py::capsule free_when_done (
143
+ xtns.data (),
144
+ [](void *cpx_ptr)
145
+ {
146
+ cpx *cpx_arr = reinterpret_cast <cpx *>(cpx_ptr);
147
+ delete[] cpx_arr;
148
+ });
149
+
130
150
// Create output array
131
151
py::array x ({m, n, p},
132
152
{sizeof (cpx),
133
153
sizeof (cpx) * m,
134
154
sizeof (cpx) * m * n},
135
- xtns.data ());
155
+ xtns.data (),
156
+ free_when_done);
136
157
137
158
// Clear output structure without deallocating
138
159
xtns._m = xtns._n = xtns._p = 0 ;
@@ -144,7 +165,10 @@ py::array_t<cpx> fdct3d_inverse_wrap(int m, int n, int p, int nbscales, int nban
144
165
PYBIND11_MODULE (fdct3d_wrapper, m)
145
166
{
146
167
m.doc () = " FDCT3D pybind11 wrapper" ;
147
- m.def (" fdct3d_param_wrap" , &fdct3d_param_wrap, " Parameters for 3D FDCT" );
148
- m.def (" fdct3d_forward_wrap" , &fdct3d_forward_wrap, " 3D Forward FDCT" );
149
- m.def (" fdct3d_inverse_wrap" , &fdct3d_inverse_wrap, " 3D Inverse FDCT" );
168
+ m.def (" fdct3d_param_wrap" , &fdct3d_param_wrap, " Parameters for 3D FDCT" ,
169
+ py::return_value_policy::take_ownership);
170
+ m.def (" fdct3d_forward_wrap" , &fdct3d_forward_wrap, " 3D Forward FDCT" ,
171
+ py::return_value_policy::take_ownership);
172
+ m.def (" fdct3d_inverse_wrap" , &fdct3d_inverse_wrap, " 3D Inverse FDCT" ,
173
+ py::return_value_policy::take_ownership);
150
174
}
0 commit comments