File indexing completed on 2026-04-09 07:49:26
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009 #include "NP.hh"
0010 #include <nanobind/nanobind.h>
0011 #include <nanobind/ndarray.h>
0012 #include <nanobind/stl/string.h>
0013
0014 struct NP_nanobind
0015 {
0016 static NP* NP_copy_of_numpy_array( nanobind::ndarray<nanobind::numpy> a) ;
0017 static NP* NP_copy_of_numpy_array_with_meta(nanobind::ndarray<nanobind::numpy> a, nanobind::str meta) ;
0018
0019 static nanobind::dlpack::dtype dtype_for_NP(char uifc, size_t ebyte);
0020 static nanobind::capsule* owner_for_NP(char uifc, size_t ebyte, void* data);
0021
0022 static nanobind::ndarray<nanobind::numpy> numpy_array_view_of_NP(const NP* a);
0023 static nanobind::tuple numpy_array_view_of_NP_with_meta(const NP* a );
0024
0025 static nanobind::ndarray<nanobind::numpy> example_numpy_array_view_of_NP(int code);
0026
0027 static nanobind::ndarray<nanobind::numpy> roundtrip_numpy_array_via_NP(nanobind::ndarray<nanobind::numpy> src);
0028 };
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 inline NP* NP_nanobind::NP_copy_of_numpy_array(nanobind::ndarray<nanobind::numpy> _a)
0040 {
0041 void* data = _a.data();
0042 size_t ndim = _a.ndim();
0043 nanobind::dlpack::dtype _dtype = _a.dtype();
0044
0045 std::string dtype ;
0046 if( _dtype == nanobind::dtype<float>() ) dtype = descr_<float>::dtype() ;
0047 else if( _dtype == nanobind::dtype<double>()) dtype = descr_<double>::dtype() ;
0048 else if( _dtype == nanobind::dtype<double>()) dtype = descr_<double>::dtype() ;
0049 else if( _dtype == nanobind::dtype<int>()) dtype = descr_<int>::dtype() ;
0050 else if( _dtype == nanobind::dtype<long>()) dtype = descr_<long>::dtype() ;
0051 else if( _dtype == nanobind::dtype<unsigned>()) dtype = descr_<unsigned>::dtype() ;
0052 else if( _dtype == nanobind::dtype<unsigned long>()) dtype = descr_<unsigned long>::dtype() ;
0053
0054 std::vector<NP::INT> shape(ndim);
0055 for(size_t i=0 ; i < ndim ; i++ ) shape[i] = _a.shape(i) ;
0056
0057 NP* a = new NP(dtype.c_str(), shape );
0058 assert( a->uarr_bytes() == _a.nbytes() );
0059 a->read_bytes( (char*)data );
0060
0061 return a ;
0062 }
0063
0064 inline NP* NP_nanobind::NP_copy_of_numpy_array_with_meta(nanobind::ndarray<nanobind::numpy> _a, nanobind::str _meta)
0065 {
0066 NP* a = NP_copy_of_numpy_array(_a);
0067 a->meta = nanobind::cast<std::string>(_meta);
0068 return a ;
0069 }
0070
0071
0072
0073 inline nanobind::dlpack::dtype NP_nanobind::dtype_for_NP(char uifc, size_t ebyte)
0074 {
0075 nanobind::dlpack::dtype dtype ;
0076 if( uifc == 'f' && ebyte == 4 ) dtype = nanobind::dtype<float>();
0077 else if( uifc == 'f' && ebyte == 8 ) dtype = nanobind::dtype<double>();
0078 else if( uifc == 'u' && ebyte == 4 ) dtype = nanobind::dtype<unsigned>();
0079 else if( uifc == 'u' && ebyte == 8 ) dtype = nanobind::dtype<unsigned long>();
0080 else if( uifc == 'i' && ebyte == 4 ) dtype = nanobind::dtype<int>();
0081 else if( uifc == 'i' && ebyte == 8 ) dtype = nanobind::dtype<long>();
0082 return dtype ;
0083 }
0084
0085 inline nanobind::capsule* NP_nanobind::owner_for_NP(char uifc, size_t ebyte, void* data)
0086 {
0087 nanobind::capsule* owner = nullptr ;
0088 if( uifc == 'f' && ebyte == 4 ) owner = new nanobind::capsule(data, [](void *p) noexcept { delete[] (float *)p ; });
0089 else if( uifc == 'f' && ebyte == 8 ) owner = new nanobind::capsule(data, [](void *p) noexcept { delete[] (double *)p ; });
0090 else if( uifc == 'u' && ebyte == 4 ) owner = new nanobind::capsule(data, [](void *p) noexcept { delete[] (unsigned *)p ; });
0091 else if( uifc == 'u' && ebyte == 8 ) owner = new nanobind::capsule(data, [](void *p) noexcept { delete[] (unsigned long *)p ; });
0092 else if( uifc == 'i' && ebyte == 4 ) owner = new nanobind::capsule(data, [](void *p) noexcept { delete[] (int *)p ; });
0093 else if( uifc == 'i' && ebyte == 8 ) owner = new nanobind::capsule(data, [](void *p) noexcept { delete[] (long *)p ; });
0094 return owner ;
0095 }
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 inline nanobind::ndarray<nanobind::numpy> NP_nanobind::numpy_array_view_of_NP(const NP* a)
0110 {
0111 void* data = (void*)a->bytes() ;
0112 std::vector<size_t> sh ;
0113 a->get_shape(sh);
0114 size_t ndim = sh.size();
0115 const size_t* shape = sh.data();
0116 nanobind::capsule* owner = owner_for_NP(a->uifc, a->ebyte, data);
0117 const int64_t* strides = nullptr ;
0118 nanobind::dlpack::dtype dtype = dtype_for_NP(a->uifc, a->ebyte);
0119 int device_type = nanobind::device::cpu::value ;
0120 int device_id = 0 ;
0121 char order = 'C' ;
0122 return nanobind::ndarray<nanobind::numpy>(data, ndim, shape, *owner, strides, dtype, device_type, device_id, order);
0123 }
0124
0125 inline nanobind::tuple NP_nanobind::numpy_array_view_of_NP_with_meta(const NP* a )
0126 {
0127 nanobind::ndarray<nanobind::numpy> arr = numpy_array_view_of_NP(a);
0128 return nanobind::make_tuple(arr, a->meta );
0129 }
0130
0131
0132 inline nanobind::ndarray<nanobind::numpy> NP_nanobind::example_numpy_array_view_of_NP(int code)
0133 {
0134 NP* a = nullptr ;
0135 switch(code)
0136 {
0137 case 0: a = NP::Make<float>(3,6,4); break ;
0138 case 1: a = NP::Make<double>(3,6,4); break ;
0139 case 2: a = NP::Make<int>(3,6,4); break ;
0140 case 3: a = NP::Make<long>(3,6,4); break ;
0141 case 4: a = NP::Make<unsigned>(3,6,4); break ;
0142 case 5: a = NP::Make<unsigned long>(3,6,4); break ;
0143 }
0144 a->fillIndexFlat();
0145 return numpy_array_view_of_NP(a);
0146 }
0147
0148
0149 inline nanobind::ndarray<nanobind::numpy> NP_nanobind::roundtrip_numpy_array_via_NP(nanobind::ndarray<nanobind::numpy> src)
0150 {
0151 NP* a_src = NP_copy_of_numpy_array(src);
0152 nanobind::ndarray<nanobind::numpy> a_dst = numpy_array_view_of_NP(a_src) ;
0153 return a_dst ;
0154 }
0155
0156
0157