-
I have the following code to dynamically allocate #include "sample.cuh"
#include <memory>
#include <nanobind/nanobind.h>
#include <nanobind/ndarray.h>
namespace nb = nanobind;
auto sample(size_t N) {
auto samples_ptr = std::make_unique<float[]>(N);
cuda_sample(samples_ptr.get(), N);
return nb::ndarray<float, nb::numpy>(samples_ptr.get(), {N}).cast();
}
NB_MODULE(sample, m) { m.def("sample", &sample); } As I understand it, in the |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
I would follow the example in https://nanobind.readthedocs.io/en/latest/ndarray.html#data-ownership The If you need to use unique_ptr for some reason (e.g., exception considerations, other functions calls not shown in your minimal example above), then you can use |
Beta Was this translation helpful? Give feedback.
-
If you are using CUDA, then I don't quite understand the reason to go through NumPy, which involves a costly (and synchronizing) GPU->CPU copy. The snippet you specified will make another copy on top of that. This is because you did not specify an owner object that will manage the lifetime of the data region. Ownership and lifetimes are described in great detail in the nanobind ndarray docs, please refer to them for more details. |
Beta Was this translation helpful? Give feedback.
I would follow the example in https://nanobind.readthedocs.io/en/latest/ndarray.html#data-ownership
Maybe, there's no reason to use a unique_ptr, since you're always using
.get()
anyway to pass the raw pointer to functions?Though, maybe you want safety if
cuda_sample
throws an exception?The
nb::ndarray
constructor in your example above is only given the raw pointer, so neither it nor the subsequent.cast()
can usestd::move
to affect the unique_ptr itself.If you need to use unique_ptr for some reason (e.g., exception considerations, other functions calls not shown in your minimal example above), then you can use
samples_ptr.release()
in thenb::ndarray
constructor so that the unique_pt…