wjakob / nanobind

nanobind: tiny and efficient C++/Python bindings
BSD 3-Clause "New" or "Revised" License
2.29k stars 191 forks source link

[BUG]: weirdness with "big" uint ndarray #488

Closed rjanvier closed 6 months ago

rjanvier commented 6 months ago

Problem description

Hi, I have some issue when returning some "big" uint nb::ndarray. I'm running macOS, but it even crashes under Linux (I'm not sure 100% though, because I tested my problematic codebase, not the minimal example). thank in advance.

Reproducible example code

//C++ part
    m.def("thebug",[](uint32_t size_a, uint32_t size_b){
        std::vector<uint64_t> indices(size_a * size_b, 0);
        std::iota(indices.begin(), indices.end(), 0);
        const size_t shape[2] = {static_cast<size_t>(size_a), static_cast<size_t>(size_b)};
        return nb::ndarray<nb::numpy, uint64_t, nb::ndim<2>>(&indices[0], 2, shape);
    });

//Python part
def test_thebug():
    print(mymodule.thebug(10000000,50))
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]]
    print(mymodule.thebug(1000,50))
[[    0     1     2 ...    47    48    49]
 [   50    51    52 ...    97    98    99]
 [  100   101   102 ...   147   148   149]
 ...
 [49850 49851 49852 ... 49897 49898 49899]
 [49900 49901 49902 ... 49947 49948 49949]
 [49950 49951 49952 ... 49997 49998 49999]]
wjakob commented 6 months ago

Please read the ndarray section carefully. Somebody need to own this data.

rjanvier commented 6 months ago

ok, thank a lot I think I got it. So it's different from pybind In this aspect. What surprise me is that it worked for the small array and I have also a bunch of other array (float ones) in my code base that just do work with the kind of "owner less" pattern I wrote in the minimal sample.

wjakob commented 6 months ago

This actually has come up several times before. I made the owner argument mandatory: https://github.com/wjakob/nanobind/commit/937a1df52428f04a0a240cc5827fb3c6769cf5c2