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,
const 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);
345 .def(
"InitPair", [](TPair &self,
const std::string &name,
const MPIInfo &mpi)
346 { self.InitPair(name, mpi); }, py::arg(
"name"), py::arg(
"mpi"))
347 .def(
"TransAttach", &TPair::TransAttach)
348 .def(
"hash", &TPair::hash)
349 .def(
"Size", &TPair::Size);
350 if constexpr (TPair::t_arr::GetDataLayoutStatic() ==
CSR)
352 .def(
"CompressBoth", &TPair::CompressBoth);
355 .def(
"to_device", [](TPair &self,
const std::string &backend)
357 .def(
"to_host", &TPair::to_host);
364 const std::string &name,
bool includePIG,
bool includeSon)
366 self.WriteSerialize(serializerP, name, includePIG, includeSon);
368 py::arg(
"serializer"), py::arg(
"name"),
369 py::arg(
"includePIG") =
true, py::arg(
"includeSon") =
true)
373 const std::string &name, std::vector<index> origIndex,
374 bool includePIG,
bool includeSon)
376 self.WriteSerialize(serializerP, name, origIndex, includePIG, includeSon);
378 py::arg(
"serializer"), py::arg(
"name"), py::arg(
"origIndex"),
379 py::arg(
"includePIG") =
true, py::arg(
"includeSon") =
true)
383 const std::string &name,
bool includePIG,
bool includeSon)
385 self.ReadSerialize(serializerP, name, includePIG, includeSon);
387 py::arg(
"serializer"), py::arg(
"name"),
388 py::arg(
"includePIG") =
true, py::arg(
"includeSon") =
true)
390 "ReadSerializeRedistributed",
392 const std::string &name, std::vector<index> newOrigIndex)
394 self.ReadSerializeRedistributed(serializerP, name, newOrigIndex);
396 py::arg(
"serializer"), py::arg(
"name"), py::arg(
"newOrigIndex"));
399 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
404 auto Pair_ = pybind11_ParArrayPair_declare<T, _row_size, _row_max, _align>(
m);
412 pybind11_ArrayPairGenericBindBasics<TPair>(Pair_);
415 .def(
"RowSize", [](
const TPair &self,
index i)
416 {
return self.RowSize(
i); }, py::arg(
"i"))
417 .def(
"RowSize", [](
const TPair &self)
418 {
return self.RowSize(); });
422 [](
const TPair &self, std::tuple<index, rowsize> index_)
424 return self(std::get<0>(index_), std::get<1>(index_));
428 [](TPair &self, std::tuple<index, rowsize> index_,
const T &value)
430 self(std::get<0>(index_), std::get<1>(index_)) = value;
434 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
440 return pybind11_ParArrayPair_define<T, _row_size, _row_max, _align>(
m);
446 template <
class TArray>
447 tPy_ArrayTransformer<TArray>
450 return {
m, pybind11_ArrayTransformer_name<TArray>().c_str()};
454 template <
class TArray>
455 tPy_ArrayTransformer<TArray>
458 return {
m.attr(pybind11_ArrayTransformer_name<TArray>().c_str())};
461 template <
class TArray>
465 auto ArrayTransformer_ = pybind11_ArrayTransformer_declare<TArray>(
m);
472#define DNDS_pybind11_array_transformer_def_ssp_property(property_name, field_name) \
474 ArrayTransformer_.def_property( \
476 [](TArrayTransformer &self) { return self.field_name; }, \
477 [](TArrayTransformer &self, decltype(TArrayTransformer::field_name) in) { self.field_name = in; }); \
487 .def(
"setFatherSon", &TArrayTransformer::setFatherSon, py::arg(
"father"), py::arg(
"son"))
488 .def(
"createFatherGlobalMapping", &TArrayTransformer::createFatherGlobalMapping)
489 .def(
"createGhostMapping", [](TArrayTransformer &self, std::vector<index> pullIndexGlobal) ->
void
490 { self.createGhostMapping(pullIndexGlobal); }, py::arg(
"pullIndexGlobal"))
491 .def(
"createGhostMapping", [](TArrayTransformer &self,
const py::array_t<index> &pullIndexGlobal)
493 std::vector<index> pullIndexVec;
494 pullIndexVec.reserve(pullIndexGlobal.size());
500 for(ssize_t
i = 0;
i < pullIndexGlobal.size();
i++)
501 pullIndexVec.push_back(pullIndexGlobal.at(
i));
503 self.createGhostMapping(pullIndexVec); }, py::arg(
"pullIndexGlobal"))
504 .def(
"createGhostMapping", [](TArrayTransformer &self, std::vector<index> pushingIndexLocal, std::vector<index> pushingStarts) ->
void
505 { self.createGhostMapping(pushingIndexLocal, pushingStarts); }, py::arg(
"pushingIndexLocal"), py::arg(
"pushingStarts"));
507 .def(
"createMPITypes", &TArrayTransformer::createMPITypes)
508 .def(
"clearMPITypes", &TArrayTransformer::clearMPITypes)
511 [](TArrayTransformer &self,
const py::object &other)
513 auto other_father = other.attr(
"father");
514 auto other_father_size = other_father.attr(
"Size")().cast<index>();
519 DNDS_assert(other_father_size == self.father->Size());
520 DNDS_assert(other_pLGhostMapping && other_pLGlobalMapping);
522 self.pLGhostMapping = other_pLGhostMapping;
523 self.pLGlobalMapping = other_pLGlobalMapping;
524 self.father->pLGlobalMapping = self.pLGlobalMapping;
529 .def(
"initPersistentPull", &TArrayTransformer::initPersistentPull, py::arg(
"backend") =
DeviceBackend::Unknown)
530 .def(
"initPersistentPush", &TArrayTransformer::initPersistentPush, py::arg(
"backend") =
DeviceBackend::Unknown)
531 .def(
"startPersistentPull", &TArrayTransformer::startPersistentPull, py::arg(
"backend") =
DeviceBackend::Unknown)
532 .def(
"startPersistentPush", &TArrayTransformer::startPersistentPush, py::arg(
"backend") =
DeviceBackend::Unknown)
533 .def(
"waitPersistentPull", &TArrayTransformer::waitPersistentPull, py::arg(
"backend") =
DeviceBackend::Unknown)
534 .def(
"waitPersistentPush", &TArrayTransformer::waitPersistentPush, py::arg(
"backend") =
DeviceBackend::Unknown)
535 .def(
"clearPersistentPull", &TArrayTransformer::clearPersistentPull)
536 .def(
"clearPersistentPush", &TArrayTransformer::clearPersistentPush)
537 .def(
"pullOnce", &TArrayTransformer::pullOnce)
538 .def(
"pushOnce", &TArrayTransformer::pushOnce);
541 template <
class T, rowsize _row_size = 1, rowsize _row_max = _row_size, rowsize _align = NoAlign>
547 return pybind11_ArrayTransformer_define<ParArray<T, _row_size, _row_max, _align>>(
m);
553 template <
int offset = 0>
561 for (
int i = 0;
i < rs;
i++)
562 ret[
i] =
i + 1 + rs * offset;
567 template <
class T,
size_t N, std::array<
int, N> const &Arr,
size_t... Is>
570 (_pybind11_Array_define_dispatch<T, Arr[Is]>(
m), ...);
573 template <
class T,
int offset = 0>
576 static constexpr auto seq = _get_pybind11_arrayRowsizeInstantiationList<offset>();
578 T, seq.size(), seq>(
m, std::make_index_sequence<seq.size()>{});
581 template <
class T,
size_t N, std::array<
int, N> const &Arr,
size_t... Is>
584 (_pybind11_ParArray_define_dispatch<T, Arr[Is]>(
m), ...);
587 template <
class T,
int offset = 0>
590 static constexpr auto seq = _get_pybind11_arrayRowsizeInstantiationList<offset>();
592 T, seq.size(), seq>(
m, std::make_index_sequence<seq.size()>{});
595 template <
class T,
size_t N, std::array<
int, N> const &Arr,
size_t... Is>
598 (_pybind11_ArrayTransformer_define_dispatch<T, Arr[Is]>(
m), ...);
601 template <
class T,
int offset = 0>
604 static constexpr auto seq = _get_pybind11_arrayRowsizeInstantiationList<offset>();
606 T, seq.size(), seq>(
m, std::make_index_sequence<seq.size()>{});
609 template <
class T,
size_t N, std::array<
int, N> const &Arr,
size_t... Is>
612 (_pybind11_ParArrayPair_define_dispatch<T, Arr[Is]>(
m), ...);
615 template <
class T,
int offset = 0>
618 static constexpr auto seq = _get_pybind11_arrayRowsizeInstantiationList<offset>();
620 T, seq.size(), seq>(
m, std::make_index_sequence<seq.size()>{});
628#define pybind11_bind_Array_All_X_declare(offset) \
629 void pybind11_bind_Array_All_##offset(py::module_ m)
631#define pybind11_bind_Array_All_X_call(offset, m) \
632 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 + ...
Eigen::Matrix< real, 3, 3 > m
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)
constexpr auto _get_pybind11_arrayRowsizeInstantiationList()
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
tPy_ParArray< T, _row_size, _row_max, _align > pybind11_ParArray_get_class(py::module_ &m)
void pybind11_callBindParArrays_rowsizes(py::module_ &m)
void pybind11_bind_Array_Offsets(const 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()
void pybind11_callBindArrayTransformers_rowsizes_sequence(py::module_ &m, std::index_sequence< Is... >)
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_callBindParArrayPairs_rowsizes_sequence(py::module_ &m, std::index_sequence< Is... >)
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
std::shared_ptr< T > ssp
Shortened alias for std::shared_ptr used pervasively in DNDSR.
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()
void pybind11_callBindParArrays_rowsizes_sequence(py::module_ &m, std::index_sequence< Is... >)
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_callBindArrays_rowsizes_sequence(py::module_ &m, std::index_sequence< Is... >)
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
solverDOF father pLGlobalMapping