18#include <pybind11/numpy.h>
19#include <pybind11/stl.h>
23 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
27 if constexpr (std::is_arithmetic_v<T>)
28 TName = py::format_descriptor<T>().format();
31 TName = T::pybind11_name();
33 return fmt::format(
"_{}_{}_{}_{}",
40 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
43 return "Array" + pybind11_Array_name_appends<T, _row_size, _row_max, _align>();
46 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
49 return "ParArray" + pybind11_Array_name_appends<T, _row_size, _row_max, _align>();
52 template <
class TArray>
55 return "ArrayTransformer" + pybind11_Array_name_appends<typename TArray::value_type, TArray::rs, TArray::rm, TArray::al>();
58 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
61 return "ParArrayPair" + pybind11_Array_name_appends<T, _row_size, _row_max, _align>();
64 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
67 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
70 template <
class TArray>
74 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
82 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
83 tPy_Array<T, _row_size, _row_max, _align>
88 pybind11_Array_name<T, _row_size, _row_max, _align>().c_str()};
92 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
93 tPy_Array<T, _row_size, _row_max, _align>
96 return {m.attr(pybind11_Array_name<T, _row_size, _row_max, _align>().c_str())};
99 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
104 auto Array_ = pybind11_Array_declare<T, _row_size, _row_max, _align>(m);
112 .def(
"Size", &TArray::Size);
114 .def(
"clone", [](TArray &self)
116 auto arr = std::make_shared<TArray>();
119 if constexpr (TArray::GetDataLayoutStatic() ==
CSR)
121 .def(
"Compress", &TArray::Compress)
122 .def(
"Decompress", &TArray::Decompress)
123 .def(
"IfCompressed", &TArray::IfCompressed);
129 if (!self.getRowStart())
130 return py::memoryview::from_buffer<index>((
index *)(&self), {0}, {
sizeof(
index)},
true);
131 auto &rs = *self.getRowStart();
132 return py::memoryview::from_buffer<index>(rs.data(), {rs.size()}, {sizeof(index)},
true);
134 py::keep_alive<0, 1>() );
141 if (!self.getRowSizes())
142 return py::memoryview::from_buffer<rowsize>((
rowsize *)(&self), {0}, {
sizeof(
rowsize)},
true);
143 auto &rs = *self.getRowSizes();
144 return py::memoryview::from_buffer<rowsize>(rs.data(), {rs.size()}, {sizeof(rowsize)},
true);
146 py::keep_alive<0, 1>() );
153 if constexpr (std::is_arithmetic_v<T>)
154 return py::memoryview::from_buffer<T>(
155 self.DataSize() ? self.data() : (T *)(&self),
156 {self.DataSize()}, {TArray::sizeof_T});
159 std::string buf_format;
160 buf_format.reserve(32);
161 for (
size_t i = 0; i < TArray::sizeof_T; i++)
163 return py::memoryview::from_buffer(
164 self.DataSize() ? self.data() : (T *)(&self),
167 {self.DataSize()}, {TArray::sizeof_T});
170 py::keep_alive<0, 1>() );
173 .def(
"Rowsize", py::overload_cast<index>(&TArray::RowSize, py::const_), py::arg(
"iRow"));
175 .def(
"Rowsize", py::overload_cast<>(&TArray::RowSize, py::const_));
177 TArray::GetDataLayoutStatic() ==
CSR ||
181 .def(
"Resize", [](TArray &self,
index nRow)
182 { self.Resize(nRow); }, py::arg(
"nRow"));
184 .def(
"Resize", [](TArray &self,
index nRow,
rowsize nRowsizeDynamic)
185 { self.Resize(nRow, nRowsizeDynamic); }, py::arg(
"nRow"), py::arg(
"rowsizeDynamic"));
186 if constexpr (TArray::isCSR)
190 [](TArray &self,
index nRow, py::array_t<int, pybind11::array::c_style | pybind11::array::forcecast> rowsizes)
192 DNDS_assert_info(rowsizes.size() >= nRow, fmt::format(
"rowsizes is of size {}, not enough", rowsizes.size()));
193 self.Resize(nRow, [&](
index iRow)
194 {
return rowsizes.at(iRow); });
196 py::arg(
"nRow"), py::arg(
"rowsizesArray"));
197 if constexpr (TArray::GetDataLayoutStatic() ==
CSR ||
198 TArray::GetDataLayoutStatic() ==
TABLE_Max ||
201 .def(
"ResizeRow", &TArray::ResizeRow, py::arg(
"iRow"), py::arg(
"nRowsize"));
204 [](
const TArray &self, std::tuple<index, rowsize> index_)
206 return self(std::get<0>(index_), std::get<1>(index_));
210 [](TArray &self, std::tuple<index, rowsize> index_,
const T &value)
212 self(std::get<0>(index_), std::get<1>(index_)) = value;
216 .def(
"to_device", [](TArray &self,
const std::string &backend)
218 .def(
"to_host", &TArray::to_host)
219 .def(
"device", &TArray::device);
222 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
228 return pybind11_Array_define<T, _row_size, _row_max, _align>(m);
235 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
236 tPy_ParArray<T, _row_size, _row_max, _align>
240 auto array_ = pybind11_Array_get_class<T, _row_size, _row_max, _align>(m);
244 pybind11_ParArray_name<T, _row_size, _row_max, _align>().c_str(),
249 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
250 tPy_ParArray<T, _row_size, _row_max, _align>
253 return {m.attr(pybind11_ParArray_name<T, _row_size, _row_max, _align>().c_str())};
256 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
260 auto ParArray_ = pybind11_ParArray_declare<T, _row_size, _row_max, _align>(m);
268 .def(py::init([](
const MPIInfo &n_mpi)
269 {
return std::make_shared<TParArray>(n_mpi); }),
271 .def(py::init([](
const std::string &name,
const MPIInfo &n_mpi)
272 {
return make_ssp<TParArray>(
ObjName{name}, n_mpi); }),
273 py::arg(
"name"), py::arg(
"n_mpi"))
274 .def(
"setObjectName", &TParArray::setObjectName, py::arg(
"name"))
275 .def(
"getObjectName", &TParArray::getObjectName)
276 .def(
"getMPI", [](
const TParArray &self)
277 {
return self.getMPI(); })
278 .def(
"setMPI", [](TParArray &self,
const MPIInfo &n_mpi)
279 { self.setMPI(n_mpi); }, py::arg(
"n_mpi"))
280 .def(
"createGlobalMapping", [](TParArray &self)
281 { self.createGlobalMapping(); })
282 .def(
"getLGlobalMapping", [](TParArray &self)
283 {
return self.pLGlobalMapping; })
284 .def(
"getTrans", [m](TParArray &self)
285 {
return py::type{m.attr(pybind11_ArrayTransformer_name<TParArray>().c_str())}; });
288 .def(
"clone", [](TParArray &self)
290 auto arr = std::make_shared<TParArray>(self.mpi);
295 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
301 return pybind11_ParArray_define<T, _row_size, _row_max, _align>(m);
308 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
309 tPy_ParArrayPair<T, _row_size, _row_max, _align>
314 pybind11_ParArrayPair_name<T, _row_size, _row_max, _align>().c_str()};
318 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
319 tPy_ParArrayPair<T, _row_size, _row_max, _align>
322 return {m.attr(pybind11_ParArrayPair_name<T, _row_size, _row_max, _align>().c_str())};
325 template <
class TPair,
class TPy_Pair>
330 {
return std::make_shared<TPair>(); }));
332 .def_readwrite(
"father", &TPair::father)
333 .def_readwrite(
"son", &TPair::son);
335 .def_readonly(
"trans", &TPair::trans, py::return_value_policy::reference_internal);
340 auto new_pair = std::make_shared<TPair>();
341 new_pair->clone(self);
346 [](TPair &self,
const std::string &name,
const MPIInfo &mpi)
347 { self.InitPair(name, mpi); },
348 py::arg(
"name"), py::arg(
"mpi"))
349 .def(
"TransAttach", &TPair::TransAttach)
350 .def(
"hash", &TPair::hash)
351 .def(
"Size", &TPair::Size);
352 if constexpr (TPair::t_arr::GetDataLayoutStatic() ==
CSR)
354 .def(
"CompressBoth", &TPair::CompressBoth);
357 .def(
"to_device", [](TPair &self,
const std::string &backend)
359 .def(
"to_host", &TPair::to_host);
366 const std::string &name,
bool includePIG,
bool includeSon)
368 self.WriteSerialize(serializerP, name, includePIG, includeSon);
370 py::arg(
"serializer"), py::arg(
"name"),
371 py::arg(
"includePIG") =
true, py::arg(
"includeSon") =
true)
375 const std::string &name, std::vector<index> origIndex,
376 bool includePIG,
bool includeSon)
378 self.WriteSerialize(serializerP, name, origIndex, includePIG, includeSon);
380 py::arg(
"serializer"), py::arg(
"name"), py::arg(
"origIndex"),
381 py::arg(
"includePIG") =
true, py::arg(
"includeSon") =
true)
385 const std::string &name,
bool includePIG,
bool includeSon)
387 self.ReadSerialize(serializerP, name, includePIG, includeSon);
389 py::arg(
"serializer"), py::arg(
"name"),
390 py::arg(
"includePIG") =
true, py::arg(
"includeSon") =
true)
392 "ReadSerializeRedistributed",
394 const std::string &name, std::vector<index> newOrigIndex)
396 self.ReadSerializeRedistributed(serializerP, name, newOrigIndex);
398 py::arg(
"serializer"), py::arg(
"name"), py::arg(
"newOrigIndex"));
401 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
406 auto Pair_ = pybind11_ParArrayPair_declare<T, _row_size, _row_max, _align>(m);
414 pybind11_ArrayPairGenericBindBasics<TPair>(Pair_);
417 .def(
"RowSize", [](
const TPair &self,
index i)
418 {
return self.RowSize(i); }, py::arg(
"i"))
419 .def(
"RowSize", [](
const TPair &self)
420 {
return self.RowSize(); });
424 [](
const TPair &self, std::tuple<index, rowsize> index_)
426 return self(std::get<0>(index_), std::get<1>(index_));
430 [](TPair &self, std::tuple<index, rowsize> index_,
const T &value)
432 self(std::get<0>(index_), std::get<1>(index_)) = value;
436 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
442 return pybind11_ParArrayPair_define<T, _row_size, _row_max, _align>(m);
448 template <
class TArray>
449 tPy_ArrayTransformer<TArray>
452 return {m, pybind11_ArrayTransformer_name<TArray>().c_str()};
456 template <
class TArray>
457 tPy_ArrayTransformer<TArray>
460 return {m.attr(pybind11_ArrayTransformer_name<TArray>().c_str())};
463 template <
class TArray>
467 auto ArrayTransformer_ = pybind11_ArrayTransformer_declare<TArray>(m);
474#define DNDS_pybind11_array_transformer_def_ssp_property(property_name, field_name) \
476 ArrayTransformer_.def_property( \
478 [](TArrayTransformer &self) { return self.field_name; }, \
479 [](TArrayTransformer &self, decltype(TArrayTransformer::field_name) in) { self.field_name = in; }); \
489 .def(
"setFatherSon", &TArrayTransformer::setFatherSon, py::arg(
"father"), py::arg(
"son"))
490 .def(
"createFatherGlobalMapping", &TArrayTransformer::createFatherGlobalMapping)
491 .def(
"createGhostMapping", [](TArrayTransformer &self, std::vector<index> pullIndexGlobal) ->
void
492 { self.createGhostMapping(pullIndexGlobal); }, py::arg(
"pullIndexGlobal"))
493 .def(
"createGhostMapping", [](TArrayTransformer &self, py::array_t<index> pullIndexGlobal)
495 std::vector<index> pullIndexVec;
496 pullIndexVec.reserve(pullIndexGlobal.size());
497 for(ssize_t i = 0; i < pullIndexGlobal.size(); i++)
498 pullIndexVec.push_back(pullIndexGlobal.at(i));
499 self.createGhostMapping(pullIndexVec); }, py::arg(
"pullIndexGlobal"))
500 .def(
"createGhostMapping", [](TArrayTransformer &self, std::vector<index> pushingIndexLocal, std::vector<index> pushingStarts) ->
void
501 { self.createGhostMapping(pushingIndexLocal, pushingStarts); }, py::arg(
"pushingIndexLocal"), py::arg(
"pushingStarts"));
503 .def(
"createMPITypes", &TArrayTransformer::createMPITypes)
504 .def(
"clearMPITypes", &TArrayTransformer::clearMPITypes)
507 [](TArrayTransformer &self, py::object other)
509 auto other_father = other.attr(
"father");
510 auto other_father_size = other_father.attr(
"Size")().cast<index>();
515 DNDS_assert(other_father_size == self.father->Size());
516 DNDS_assert(other_pLGhostMapping && other_pLGlobalMapping);
518 self.pLGhostMapping = other_pLGhostMapping;
519 self.pLGlobalMapping = other_pLGlobalMapping;
520 self.father->pLGlobalMapping = self.pLGlobalMapping;
525 .def(
"initPersistentPull", &TArrayTransformer::initPersistentPull, py::arg(
"backend") =
DeviceBackend::Unknown)
526 .def(
"initPersistentPush", &TArrayTransformer::initPersistentPush, py::arg(
"backend") =
DeviceBackend::Unknown)
527 .def(
"startPersistentPull", &TArrayTransformer::startPersistentPull, py::arg(
"backend") =
DeviceBackend::Unknown)
528 .def(
"startPersistentPush", &TArrayTransformer::startPersistentPush, py::arg(
"backend") =
DeviceBackend::Unknown)
529 .def(
"waitPersistentPull", &TArrayTransformer::waitPersistentPull, py::arg(
"backend") =
DeviceBackend::Unknown)
530 .def(
"waitPersistentPush", &TArrayTransformer::waitPersistentPush, py::arg(
"backend") =
DeviceBackend::Unknown)
531 .def(
"clearPersistentPull", &TArrayTransformer::clearPersistentPull)
532 .def(
"clearPersistentPush", &TArrayTransformer::clearPersistentPush)
533 .def(
"pullOnce", &TArrayTransformer::pullOnce)
534 .def(
"pushOnce", &TArrayTransformer::pushOnce);
537 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
543 return pybind11_ArrayTransformer_define<ParArray<T, _row_size, _row_max, _align>>(m);
549 template <
int offset = 0>
557 for (
int i = 0; i < rs; i++)
558 ret[i] = i + 1 + rs * offset;
563 template <
class T,
size_t N, std::array<
int, N> const &Arr,
size_t... Is>
566 (_pybind11_Array_define_dispatch<T, Arr[Is]>(m), ...);
569 template <
class T,
int offset = 0>
572 static constexpr auto seq = _get_pybind11_arrayRowsizeInstantiationList<offset>();
574 T, seq.size(), seq>(m, std::make_index_sequence<seq.size()>{});
577 template <
class T,
size_t N, std::array<
int, N> const &Arr,
size_t... Is>
580 (_pybind11_ParArray_define_dispatch<T, Arr[Is]>(m), ...);
583 template <
class T,
int offset = 0>
586 static constexpr auto seq = _get_pybind11_arrayRowsizeInstantiationList<offset>();
588 T, seq.size(), seq>(m, std::make_index_sequence<seq.size()>{});
591 template <
class T,
size_t N, std::array<
int, N> const &Arr,
size_t... Is>
594 (_pybind11_ArrayTransformer_define_dispatch<T, Arr[Is]>(m), ...);
597 template <
class T,
int offset = 0>
600 static constexpr auto seq = _get_pybind11_arrayRowsizeInstantiationList<offset>();
602 T, seq.size(), seq>(m, std::make_index_sequence<seq.size()>{});
605 template <
class T,
size_t N, std::array<
int, N> const &Arr,
size_t... Is>
608 (_pybind11_ParArrayPair_define_dispatch<T, Arr[Is]>(m), ...);
611 template <
class T,
int offset = 0>
614 static constexpr auto seq = _get_pybind11_arrayRowsizeInstantiationList<offset>();
616 T, seq.size(), seq>(m, std::make_index_sequence<seq.size()>{});
624#define pybind11_bind_Array_All_X_declare(offset) \
625 void pybind11_bind_Array_All_##offset(py::module_ m)
627#define pybind11_bind_Array_All_X_call(offset, m) \
628 pybind11_bind_Array_All_##offset(m)
Father-son array pairs with device views and ghost communication.
Core 2D variable-length array container with five data layouts.
#define DNDS_pybind11_array_transformer_def_ssp_property(property_name, field_name)
#define pybind11_bind_Array_All_X_call(offset, m)
#define pybind11_bind_Array_All_X_declare(offset)
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
Shared pybind11 plumbing used by every *_bind.hpp in DNDS (buffer-protocol type check,...
Device memory abstraction layer with backend-specific storage and factory creation.
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
Base types and abstract interface for array serialization.
Core 2D variable-length array container, the storage foundation of DNDSR.
MPI-aware Array: adds a communicator, rank, and global index mapping.
ssp< SerializerBase > SerializerBaseSSP
the host side operators are provided as implemented
void pybind11_Array_define(py::module_ &m)
void _pybind11_ArrayTransformer_define_dispatch(py::module_ &m)
void pybind11_bind_Array_Offsets(py::module_ m)
constexpr auto _get_pybind11_arrayRowsizeInstantiationList()
void __pybind11_callBindArrays_rowsizes_sequence(py::module_ &m, std::index_sequence< Is... >)
void _pybind11_ParArray_define_dispatch(py::module_ &m)
@ Unknown
Unset / sentinel.
py_class_ssp< ParArray< T, _row_size, _row_max, _align > > tPy_ParArray
py::classh< T > py_class_ssp
void __pybind11_callBindArrayTransformers_rowsizes_sequence(py::module_ &m, std::index_sequence< Is... >)
tPy_ParArray< T, _row_size, _row_max, _align > pybind11_ParArray_get_class(py::module_ &m)
void pybind11_callBindParArrays_rowsizes(py::module_ &m)
void pybind11_callBindArrayTransformers_rowsizes(py::module_ &m)
void pybind11_ArrayPairGenericBindBasics(TPy_Pair &Pair_)
tPy_Array< T, _row_size, _row_max, _align > pybind11_Array_declare(py::module_ &m)
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
void pybind11_callBindParArrayPairs_rowsizes(py::module_ &m)
tPy_ArrayTransformer< TArray > pybind11_ArrayTransformer_get_class(py::module_ &m)
void pybind11_ArrayTransformer_define(py::module_ &m)
std::string pybind11_Array_name_appends()
std::string pybind11_ParArrayPair_name()
DeviceBackend device_backend_name_to_enum(std::string_view s)
Inverse of device_backend_name. Returns Unknown for unrecognised names.
std::string pybind11_ParArray_name()
@ TABLE_StaticFixed
Fixed row width, known at compile time.
@ TABLE_Max
Padded variable rows; max width set at runtime.
@ CSR
Compressed Sparse Row (flat buffer + row-start index).
@ TABLE_StaticMax
Padded variable rows; max width fixed at compile time.
tPy_ParArray< T, _row_size, _row_max, _align > pybind11_ParArray_declare(py::module_ &m)
void _pybind11_Array_define_dispatch(py::module_ &m)
std::string RowSize_To_PySnippet(rowsize rs)
Encode a rowsize constant as a short Python-binding snippet: "<number>" for fixed,...
tPy_ArrayTransformer< TArray > pybind11_ArrayTransformer_declare(py::module_ &m)
std::string pybind11_ArrayTransformer_name()
void pybind11_callBindArrays_rowsizes(py::module_ &m)
py_class_ssp< ArrayTransformerType_t< TArray > > tPy_ArrayTransformer
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
py_class_ssp< Array< T, _row_size, _row_max, _align > > tPy_Array
void __pybind11_callBindParArrayPairs_rowsizes_sequence(py::module_ &m, std::index_sequence< Is... >)
std::shared_ptr< T > ssp
Shortened alias for std::shared_ptr used pervasively in DNDSR.
void __pybind11_callBindParArrays_rowsizes_sequence(py::module_ &m, std::index_sequence< Is... >)
tPy_Array< T, _row_size, _row_max, _align > pybind11_Array_get_class(py::module_ &m)
void _pybind11_ParArrayPair_define_dispatch(py::module_ &m)
py_class_ssp< ArrayPair< ParArray< T, _row_size, _row_max, _align > > > tPy_ParArrayPair
std::string pybind11_Array_name()
std::string Align_To_PySnippet(rowsize al)
Encode an alignment value as a Python-binding snippet: "N" for NoAlign, the number otherwise.
void pybind11_ParArray_define(py::module_ &m)
typename ArrayTransformerType< TArray >::Type ArrayTransformerType_t
void pybind11_bind_Array_All(py::module_ m)
void pybind11_ParArrayPair_define(py::module_ &m)
DNDS_CONSTANT const rowsize UnInitRowsize
Sentinel "not initialised" rowsize value (= INT32_MIN).
tPy_ParArrayPair< T, _row_size, _row_max, _align > pybind11_ParArrayPair_declare(py::module_ &m)
tPy_ParArrayPair< T, _row_size, _row_max, _align > pybind11_ParArrayPair_get_class(py::module_ &m)
Convenience bundle of a father, son, and attached ArrayTransformer.
Lightweight bundle of an MPI communicator and the calling rank's coordinates.
Tag type for naming objects created via make_ssp.
Eigen::Matrix< real, 5, 1 > v