-
Using either v1.8 or latest, when passing an ndarray created in python it doesn't seem to be doing anything with the contig template parameter. I've tried with both explicit method overloads and C++: void check_contig(nb::ndarray<float, nb::ndim<1>>&) {
std::cout << "1-d array" << std::endl;
}
void check_contig(nb::ndarray<float, nb::ndim<2>, nb::c_contig>&) {
std::cout << "C, 2-d matrix" << std::endl;
}
void check_contig(nb::ndarray<float, nb::ndim<2>, nb::f_contig>&) {
std::cout << "Fortran, 2-d matrix" << std::endl;
}
void check_contig(nb::ndarray<float, nb::ndim<2>, nb::any_contig>&) {
std::cout << "?, 2-d matrix" << std::endl;
}
m.def("check_contig", [](nb::ndarray<float, nb::ndim<1>>& v) { check_contig(v);}, nb::arg("vec"), "1-d array")
.def("check_contig", [](nb::ndarray<float, nb::ndim<2>, nb::c_contig>& m) { check_contig(m); }, nb::arg("mat"), "2-d array, C")
.def("check_contig", [](nb::ndarray<float, nb::ndim<2>, nb::f_contig>& m) { check_contig(m); }, nb::arg("mat"), "2-d array, Fortran")
.def("check_contig", [](nb::ndarray<float, nb::ndim<2>, nb::any_contig>& m) { check_contig(m); }, nb::arg("mat"), "2-d array, Any")
; Python: vec = np.array([1,2,3])
check_contig(vec)
mat1 = np.array([[1,2,3],[4,5,6]])
check_contig(mat1)
print(mat1.flags)
mat2 = np.array([[1,2,3],[4,5,6]], order='F')
check_contig(mat2)
print(mat2.flags) And the output:
It's clearly getting the 1-d array correct. For the 2-d portion it always dispatches to the first one defined regardless of input. Adding an explicit Any tips on what I'm doing wrong here are appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
The ndarray annotations are only used at the Python <-> CPP boundary. Relying on this for function overload resolution and/or implicit conversions within C++ is not an anticipated use case. It is not surprising to me that it is not behaving as expected in your example. It might be quite hard to support this since |
Beta Was this translation helpful? Give feedback.
-
Thank you for such a quick reply. I think I was considering the dispatching to be part of that interface, but it makes sense that the actual Python->CPP interface is prior to that (unidirectional in this example). The answer seems to be to allow a user-specified flag to change behavior where it matters. |
Beta Was this translation helpful? Give feedback.
The ndarray annotations are only used at the Python <-> CPP boundary. Relying on this for function overload resolution and/or implicit conversions within C++ is not an anticipated use case. It is not surprising to me that it is not behaving as expected in your example.
It might be quite hard to support this since
ndarray
intentionally forgets about what framework created the ndarray following type casting/implicit conversions and the eventual creation of the wrapper around a DLPack tensor. If you need further implicit conversions later on, there is no infrastructure to do so. (The tensor might, e.g., live on the GPU, but nanobind does not link to any GPU frameworks to facilitate copying/r…