From 7b6e7886a343c301e42d26fa9be05d425efe5d2a Mon Sep 17 00:00:00 2001 From: Casper da Costa-Luis Date: Wed, 13 Mar 2024 19:25:59 +0000 Subject: [PATCH 1/2] add CPU-only vectors --- cuvec/include/cuvec.cuh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cuvec/include/cuvec.cuh b/cuvec/include/cuvec.cuh index 9b69804..aaa23a2 100644 --- a/cuvec/include/cuvec.cuh +++ b/cuvec/include/cuvec.cuh @@ -82,7 +82,7 @@ template bool operator!=(const CuAlloc &, const CuAlloc return false; } -template using CuVec = std::vector>; +template > using CuVec = std::vector; /// extension helpers #ifndef _CUVEC_HALF @@ -97,8 +97,8 @@ template using CuVec = std::vector>; #endif // _CUVEC_HALF /// external wrapper helper -template struct NDCuVec { - CuVec vec; +template > struct NDCuVec { + CuVec vec; std::vector shape; NDCuVec() = default; NDCuVec(const std::vector &shape) : shape(shape) { @@ -121,4 +121,8 @@ template struct NDCuVec { } }; +/// CPU-only versions +template using CVec = std::vector>; +template using NDCVec = NDCuVec>; + #endif // _CUVEC_H_ From ae2e00945433d4ce77586da509629e81de3614fb Mon Sep 17 00:00:00 2001 From: Casper da Costa-Luis Date: Wed, 13 Mar 2024 19:50:35 +0000 Subject: [PATCH 2/2] pybind11: expose CPU-only --- cuvec/include/cuvec_pybind11.cuh | 52 +++++++++++++++++++++----------- cuvec/src/pybind11.cu | 24 +++++++-------- 2 files changed, 46 insertions(+), 30 deletions(-) diff --git a/cuvec/include/cuvec_pybind11.cuh b/cuvec/include/cuvec_pybind11.cuh index 999be18..d76e900 100644 --- a/cuvec/include/cuvec_pybind11.cuh +++ b/cuvec/include/cuvec_pybind11.cuh @@ -9,29 +9,36 @@ #include // pybind11, PYBIND11_MAKE_OPAQUE #include // std::vector +#ifndef CUVEC_DISABLE_CUDA // ensure CPU-only alternative exists +#define NDxVEC_MAKE_OPAQUE(T) \ + PYBIND11_MAKE_OPAQUE(NDCuVec); \ + PYBIND11_MAKE_OPAQUE(NDCVec); +#else +#define NDxVEC_MAKE_OPAQUE(T) PYBIND11_MAKE_OPAQUE(NDCuVec); +#endif // CUVEC_DISABLE_CUDA + PYBIND11_MAKE_OPAQUE(std::vector); -PYBIND11_MAKE_OPAQUE(NDCuVec); -PYBIND11_MAKE_OPAQUE(NDCuVec); -PYBIND11_MAKE_OPAQUE(NDCuVec); -PYBIND11_MAKE_OPAQUE(NDCuVec); -PYBIND11_MAKE_OPAQUE(NDCuVec); -PYBIND11_MAKE_OPAQUE(NDCuVec); -PYBIND11_MAKE_OPAQUE(NDCuVec); -PYBIND11_MAKE_OPAQUE(NDCuVec); -PYBIND11_MAKE_OPAQUE(NDCuVec); +NDxVEC_MAKE_OPAQUE(signed char); +NDxVEC_MAKE_OPAQUE(unsigned char); +NDxVEC_MAKE_OPAQUE(char); +NDxVEC_MAKE_OPAQUE(short); +NDxVEC_MAKE_OPAQUE(unsigned short); +NDxVEC_MAKE_OPAQUE(int); +NDxVEC_MAKE_OPAQUE(unsigned int); +NDxVEC_MAKE_OPAQUE(long long); +NDxVEC_MAKE_OPAQUE(unsigned long long); #ifdef _CUVEC_HALF -PYBIND11_MAKE_OPAQUE(NDCuVec<_CUVEC_HALF>); +NDxVEC_MAKE_OPAQUE(_CUVEC_HALF); template <> struct pybind11::format_descriptor<_CUVEC_HALF> : pybind11::format_descriptor { static std::string format() { return "e"; } }; #endif -PYBIND11_MAKE_OPAQUE(NDCuVec); -PYBIND11_MAKE_OPAQUE(NDCuVec); +NDxVEC_MAKE_OPAQUE(float); +NDxVEC_MAKE_OPAQUE(double); -#define PYBIND11_BIND_NDCUVEC(T, typechar) \ - pybind11::class_>(m, PYBIND11_TOSTRING(NDCuVec_##typechar), \ - pybind11::buffer_protocol()) \ - .def_buffer([](NDCuVec &v) -> pybind11::buffer_info { \ +#define PYBIND11_BIND_NDVEC(Vec, T, typechar) \ + pybind11::class_>(m, PYBIND11_TOSTRING(Vec##_##typechar), pybind11::buffer_protocol()) \ + .def_buffer([](Vec &v) -> pybind11::buffer_info { \ return pybind11::buffer_info(v.vec.data(), sizeof(T), \ pybind11::format_descriptor::format(), v.shape.size(), \ v.shape, v.strides()); \ @@ -39,7 +46,16 @@ PYBIND11_MAKE_OPAQUE(NDCuVec); .def(pybind11::init<>()) \ .def(pybind11::init>()) \ .def_property( \ - "shape", [](const NDCuVec &v) { return &v.shape; }, &NDCuVec::reshape) \ - .def_property_readonly("address", [](const NDCuVec &v) { return (size_t)v.vec.data(); }) + "shape", [](const Vec &v) { return &v.shape; }, &Vec::reshape) \ + .def_property_readonly("address", [](const Vec &v) { return (size_t)v.vec.data(); }) +#define PYBIND11_BIND_NDCUVEC(T, typechar) PYBIND11_BIND_NDVEC(NDCuVec, T, typechar) +#ifndef CUVEC_DISABLE_CUDA // ensure CPU-only alternative exists +#define PYBIND11_BIND_NDCVEC(T, typechar) PYBIND11_BIND_NDVEC(NDCVec, T, typechar) +#else +#define PYBIND11_BIND_NDCVEC(T, typechar) +#endif // CUVEC_DISABLE_CUDA +#define PYBIND11_BIND_NDxVEC(T, typechar) \ + PYBIND11_BIND_NDCVEC(T, typechar); \ + PYBIND11_BIND_NDCUVEC(T, typechar) #endif // _CUVEC_PYBIND11_H_ diff --git a/cuvec/src/pybind11.cu b/cuvec/src/pybind11.cu index 064c30b..445e4fa 100644 --- a/cuvec/src/pybind11.cu +++ b/cuvec/src/pybind11.cu @@ -11,20 +11,20 @@ PYBIND11_MODULE(cuvec_pybind11, m) { m.doc() = "PyBind11 external module."; pybind11::bind_vector>(m, "Shape"); pybind11::implicitly_convertible>(); - PYBIND11_BIND_NDCUVEC(signed char, b); - PYBIND11_BIND_NDCUVEC(unsigned char, B); - PYBIND11_BIND_NDCUVEC(char, c); - PYBIND11_BIND_NDCUVEC(short, h); - PYBIND11_BIND_NDCUVEC(unsigned short, H); - PYBIND11_BIND_NDCUVEC(int, i); - PYBIND11_BIND_NDCUVEC(unsigned int, I); - PYBIND11_BIND_NDCUVEC(long long, q); - PYBIND11_BIND_NDCUVEC(unsigned long long, Q); + PYBIND11_BIND_NDxVEC(signed char, b); + PYBIND11_BIND_NDxVEC(unsigned char, B); + PYBIND11_BIND_NDxVEC(char, c); + PYBIND11_BIND_NDxVEC(short, h); + PYBIND11_BIND_NDxVEC(unsigned short, H); + PYBIND11_BIND_NDxVEC(int, i); + PYBIND11_BIND_NDxVEC(unsigned int, I); + PYBIND11_BIND_NDxVEC(long long, q); + PYBIND11_BIND_NDxVEC(unsigned long long, Q); #ifdef _CUVEC_HALF - PYBIND11_BIND_NDCUVEC(_CUVEC_HALF, e); + PYBIND11_BIND_NDxVEC(_CUVEC_HALF, e); #endif - PYBIND11_BIND_NDCUVEC(float, f); - PYBIND11_BIND_NDCUVEC(double, d); + PYBIND11_BIND_NDxVEC(float, f); + PYBIND11_BIND_NDxVEC(double, d); m.attr("__author__") = "Casper da Costa-Luis (https://github.com/casperdcl)"; m.attr("__date__") = "2024"; m.attr("__version__") = "2.0.0";