DNDSR 0.1.0.dev1+gcd065ad
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
Defines_bind.hpp
Go to the documentation of this file.
1#pragma once
2/// @file Defines_bind.hpp
3/// @brief Shared pybind11 plumbing used by every `*_bind.hpp` in DNDS
4/// (buffer-protocol type check, ssp-based class alias, ostream redirect guard,
5/// top-level `pybind11_bind_defines` entry point).
6
7#include "Defines.hpp"
8#ifdef DNDS_USE_OMP
9#include <omp.h>
10#endif
11#include <pybind11/pybind11.h>
12#include <pybind11/iostream.h>
13namespace py = pybind11;
14
15namespace DNDS
16{
17#define DNDS_PYBIND11_OSTREAM_GUARD py::call_guard<py::scoped_ostream_redirect, \
18 py::scoped_estream_redirect>()
19
20 template <class T>
21 using py_class_ssp = py::classh<T>;
22
23 template <class T>
24 bool py_buffer_contains_T(const py::buffer_info &info)
25 {
26 // return info.format == py::format_descriptor<T>::format(); // this could cause misjudge like long vs long long
27 return info.item_type_is_equivalent_to<T>();
28 }
29
30 inline bool py_buffer_is_contigious_c(const py::buffer_info &info)
31 {
32 bool is_contiguous = true;
33 ssize_t stride = info.itemsize;
34 for (int i = info.ndim - 1; i >= 0; --i)
35 {
36 if (info.strides[i] != stride)
37 {
38 is_contiguous = false;
39 break;
40 }
41 stride *= info.shape[i];
42 }
43 return is_contiguous;
44 }
45
46 inline bool py_buffer_is_contigious_f(const py::buffer_info &info)
47 {
48 bool is_contiguous = true;
49 ssize_t stride = info.itemsize;
50 for (int i = 0; i < info.ndim; ++i)
51 {
52 if (info.strides[i] != stride)
53 {
54 is_contiguous = false;
55 break;
56 }
57 stride *= info.shape[i];
58 }
59 return is_contiguous;
60 }
61
62 inline std::tuple<ssize_t, char> py_buffer_get_contigious_size(const py::buffer_info &info)
63 {
64 if (info.ndim == 0)
65 return {1, 'A'};
66 char style = 'N';
68 style = 'C';
69 else if (py_buffer_is_contigious_f(info))
70 style = 'F';
71 else
72 DNDS_assert_info(false, "the data layout is neither C or F contigious");
73 return {info.size, style};
74 }
75
76 template <typename T>
77 py::memoryview py_vector_as_memory_view(std::vector<T> &vec, bool readonly)
78 {
79 return py::memoryview::from_buffer<T>(
80 vec.data(),
81 {vec.size()},
82 {sizeof(T)},
83 true);
84 }
85
86 inline void pybind11_bind_defines(py::module_ &m)
87 {
88 m
89 .def("_get_UnInitReal", []()
90 { return UnInitReal; })
91 .def("_get_UnInitIndex", []()
92 { return UnInitIndex; })
93 .def("_get_UnInitRowsize", []()
94 { return UnInitRowsize; });
95
96 m.attr("UnInitReal") = py::float_(UnInitReal);
97 m.attr("UnInitIndex") = py::int_(UnInitIndex);
98 m.attr("UnInitRowsize") = py::int_(UnInitRowsize);
99
100#ifdef DNDS_USE_OMP
101 m.def("omp_set_num_threads", [](int n)
102 { omp_set_num_threads(n); });
103#endif
104 }
105}
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
Definition Errors.hpp:113
the host side operators are provided as implemented
DNDS_CONSTANT const index UnInitIndex
Sentinel "not initialised" index value (= INT64_MIN).
Definition Defines.hpp:176
py::classh< T > py_class_ssp
std::tuple< ssize_t, char > py_buffer_get_contigious_size(const py::buffer_info &info)
DNDS_CONSTANT const real UnInitReal
Sentinel "not initialised" real value (NaN). Cheap to detect with std::isnan or IsUnInitReal; survive...
Definition Defines.hpp:174
void pybind11_bind_defines(py::module_ &m)
bool py_buffer_is_contigious_c(const py::buffer_info &info)
bool py_buffer_contains_T(const py::buffer_info &info)
py::memoryview py_vector_as_memory_view(std::vector< T > &vec, bool readonly)
DNDS_CONSTANT const rowsize UnInitRowsize
Sentinel "not initialised" rowsize value (= INT32_MIN).
Definition Defines.hpp:179
bool py_buffer_is_contigious_f(const py::buffer_info &info)
Eigen::Vector3d n(1.0, 0.0, 0.0)