I wonder if anyone has insights into nanobind for returning a ndarray
from c++ to python.
I am simply wanting to return a ndarray
with a given size, which I fill with data. I do not want to manage the memory by c++. So I would do something like:
...
.def("test", []() {
std::array a {10.0, 20.0};
return nanobind::ndarray<nb::numpy, double>(a.data(), { a.size() }, nanobind::handle());
})
...
While this seems to work, I am not sure, whether it is correct or whether I am introducing a memory leak and the array points to memory which freed after having left the function. In the documentation there is talk about ownership and creating a capsule, which handles the memory. While this might make sense for large arrays, it seems overly complex for small arrays.
There is also an example where just the nanobind::handle()
(as in the snipped above) is used as owner, but in the specific example, the underlying data is not freed anyway since it is defined in global space.
As an alternative one could think about creating a ndarray
first, which allocates its memory and then fill it afterwards. Something like
...
.def("test", []() {
nb::ndarray<nb::numpy, nb::shape<100>, double> result; // array with allocated memory
std::span<double> view(result.data(), result.data()+result.size();
std::fill(view.begin(), view.end(), 100); // arbitrary function to fill the ndarray ....
return result;
}
...
But this example does not work and I did not find any constructors or factories which would provide similar functionality.
I am also wondering: Am I overseeing something obvious here? Is this something, which is normally not needed, since there are better solutions for such problems?