30#if defined(linux) || defined(_UNIX) || defined(__linux__) || defined(__unix__) || defined(__APPLE__)
31# define DNDS_UNIX_LIKE
38#if defined(_WIN32) || defined(__WINDOWS_)
43#define DNDS_FMT_ARG(V) fmt::arg(#V, V)
66# include <cuda_runtime.h>
69#if defined(DNDS_USE_CUDA)
70# define DNDS_DEVICE_CALLABLE __host__ __device__
71# define DNDS_DEVICE __device__
72# define DNDS_HOST __host__
73# define DNDS_GLOBAL __global__
74# define DNDS_CONSTANT __constant__
76# define DNDS_DEVICE_CALLABLE
83#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE(T, T_Self) \
84 DNDS_DEVICE_CALLABLE T() = default; \
85 DNDS_DEVICE_CALLABLE T(const T_Self &) = default; \
86 DNDS_DEVICE_CALLABLE T(T_Self &&) = default; \
87 DNDS_DEVICE_CALLABLE T &operator=(const T_Self &) = default; \
88 DNDS_DEVICE_CALLABLE T &operator=(T_Self &&) = default; \
89 DNDS_DEVICE_CALLABLE ~T() = default;
91#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE_NO_EMPTY_CTOR(T, T_Self) \
92 DNDS_DEVICE_CALLABLE T(const T_Self &) = default; \
93 DNDS_DEVICE_CALLABLE T(T_Self &&) = default; \
94 DNDS_DEVICE_CALLABLE T &operator=(const T_Self &) = default; \
95 DNDS_DEVICE_CALLABLE T &operator=(T_Self &&) = default; \
96 DNDS_DEVICE_CALLABLE ~T() = default;
100static_assert(
sizeof(uint8_t) == 1,
"bad uint8_t");
116#define DNDS_INDEX_MAX INT64_MAX
117#define DNDS_INDEX_MIN INT64_MIN
118#define DNDS_ROWSIZE_MAX INT32_MAX
119#define DNDS_ROWSIZE_MIN INT32_MIN
122 static const char *outputDelim =
"\t";
137 template <
typename T>
138 using ssp = std::shared_ptr<T>;
141 template <
typename T>
146 template <
typename T>
151 template <
typename T>
155 template <
typename T>
186 return std::isnan(
v);
197#define DNDS_E_PI 3.1415926535897932384626433832795028841971693993751058209749445923078164062
202 using tDiFj = Eigen::Matrix<
real, -1, -1, Eigen::RowMajor>;
205 using MatrixXR = Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic>;
207 using VectorXR = Eigen::Vector<real, Eigen::Dynamic>;
212#define DNDS_MAKE_SSP(ssp, ...) (ssp = std::make_shared<typename decltype(ssp)::element_type>(__VA_ARGS__))
222 std::string _objectName;
233 [[nodiscard]]
const std::string &
getObjectName()
const {
return _objectName; }
239 if (_objectName.empty())
241 return fmt::format(
"{}({})", _objectName, sig);
254 template <
typename T,
typename... Args>
257 return std::make_shared<T>(std::forward<Args>(args)...);
263 template <
typename T,
typename... Args>
266 auto p = std::make_shared<T>(std::forward<Args>(args)...);
267 if constexpr (std::is_base_of_v<ObjectNaming, T>)
268 p->setObjectName(objName.
name);
297 return fmt::format(
"{}", rs);
317 return fmt::format(
"{}", al);
379 template <
typename T>
382 static_assert(std::is_signed_v<T> && std::is_integral_v<T>,
"T must be a signed integral type");
383 if (increment > 0 && value > std::numeric_limits<T>::max() - increment)
385 if (increment < 0 && value < std::numeric_limits<T>::min() - increment)
393 template <
typename T>
396 static_assert(std::is_signed_v<T> && std::is_integral_v<T>,
"T must be a signed integral type");
397 if (signedIntWillAddOverflow<T>(value, increment))
399 DNDS_assert_info(
false, fmt::format(
"doing [{} + {}] overflow detected", value, increment));
402 return value + increment;
408 template <
typename T>
411 static_assert(std::is_signed_v<T> && std::is_integral_v<T>,
"T must be a signed integral type");
412 static_assert(std::is_unsigned_v<size_t>,
"size_t should be unsigned");
413 if (
v <= std::numeric_limits<T>::max())
417 DNDS_assert_info(
false, fmt::format(
"[{}] from {} to size_t overflow detected",
v,
typeid(T).name()));
428 return size_t_to_signed<index>(
v);
435 return size_t_to_signed<rowsize>(
v);
451 template <
class TtRowsizeVec,
class TtIndexVec>
454 static_assert(std::is_signed_v<typename TtIndexVec::value_type>,
"row starts should be signed");
455 static_assert(std::numeric_limits<typename TtIndexVec::value_type>::max() >=
456 std::numeric_limits<typename TtRowsizeVec::value_type>::max(),
457 "row starts should have larger upper limit");
458 rowstarts.resize(rowsizes.size() + 1);
460 for (
typename TtIndexVec::size_type i = 1; i < rowstarts.size(); i++)
462 rowstarts[i] = signedIntSafeAdd<typename TtIndexVec::value_type>(rowstarts[i - 1], rowsizes[i - 1]);
474 for (
auto i = 1; i < dat.size(); i++)
483 template <
class T,
class TP = T>
484 inline void PrintVec(
const std::vector<T> &dat, std::ostream &out)
486 for (
auto i = 0; i < dat.size(); i++)
487 out << TP(dat[i]) << outputDelim;
494 template <
class TL,
class TR>
497 return l /
r + (l %
r) ? 1 : 0;
516 template <
typename T>
517 constexpr T
sqr(
const T &a)
519 static_assert(std::is_arithmetic_v<T>,
"need arithmetic");
524 template <
typename T>
527 static_assert(std::is_arithmetic_v<T>,
"need arithmetic");
534 return a > 0 ? 1 : (a < 0 ? -1 : 0);
540 return a > tol ? 1 : (a < -tol ? -1 : 0);
546 return a >= 0 ? 1 : -1;
552 return a <= 0 ? -1 : 1;
557 template <
typename T>
560 static_assert(std::is_signed<T>::value && std::is_integral<T>::value,
"not legal mod type");
568 template <
typename T>
571 static_assert(std::is_integral<T>::value,
"not legal mod type");
572 return a /
b + (a %
b ? 1 : 0);
582 return a - std::floor(a /
b) *
b;
595 template <
class tIt1,
class tIt1end,
class tIt2,
class tIt2end,
class tF>
598 size_t it1Pos{0}, it2Pos{0};
599 while (it1 != it1end && it2 != it2end)
603 else if ((*it1) > (*it2))
605 else if ((*it1) == (*it2))
607 if (F(*it1, it1Pos, it2Pos))
622 fmt::format(
"Index {} to int32 overflow",
v));
623 return static_cast<int32_t
>(
v);
635 return std::string{
v};
643#if EIGEN_MAJOR_VERSION >= 5
645 static const auto EigenAll = Eigen::placeholders::all;
647 static const auto EigenLast = Eigen::placeholders::last;
649 static const auto EigenAll = Eigen::all;
650 static const auto EigenLast = Eigen::last;
659 template <
typename T>
668 template <
class T,
size_t N>
679 template <
class T,
class Allocator>
684 template <
typename _Tp>
687 static_assert(is_std_array_v<std::array<real, 5>> && (!is_std_array_v<std::vector<real>>));
712 static constexpr bool value =
false;
715 template <
class T,
int M,
int N,
int options,
int max_m,
int max_n>
718 static constexpr bool value = std::is_same_v<real, T> &&
720 (max_m > 0 && max_n > 0));
723 template <
typename _Tp>
726 static_assert(!is_fixed_data_real_eigen_matrix_v<std::array<real, 10>> &&
727 is_fixed_data_real_eigen_matrix_v<Eigen::Matrix<real, 2, 2>> &&
729 is_fixed_data_real_eigen_matrix_v<Eigen::Vector2d> &&
730 !is_fixed_data_real_eigen_matrix_v<Eigen::Vector2f> &&
733 !is_fixed_data_real_eigen_matrix_v<Eigen::MatrixXd>,
734 "is_fixed_data_real_eigen_matrix_v bad");
736 template <
typename T>
743 static constexpr bool value =
false;
746 template <
int M,
int N,
int options,
int max_m,
int max_n>
756 template <
typename T,
typename =
void>
761 template <
typename T>
762 struct has_std_hash<T, std::void_t<decltype(std::hash<T>{}(std::declval<T>()))>> : std::true_type
772 inline std::vector<std::string>
splitSString(
const std::string &str,
char delim)
774 std::vector<std::string> ret;
777 while (top < str.size() + 1)
779 if (str[top] != delim && top != str.size())
784 ret.push_back(str.substr(bot, top - bot));
792 std::vector<std::string> ret0 =
splitSString(str, delim);
793 std::vector<std::string> ret;
802 if (str.size() < suffix.size())
804 return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
808 template <
typename T>
816 r =
r ^ std::hash<T>{}(i);
822 for (
size_t i = 0; i <
v.size() *
sizeof(T); i++)
823 r =
r ^ std::hash<uint8_t>{}(((uint8_t *)(
v.data()))[i]);
828 template <
class TBegin,
class TEnd>
829 std::size_t
operator()(TBegin &&begin, TEnd &&end)
const noexcept
832 ptrdiff_t size = end - begin;
834 for (ptrdiff_t i = 0; i < size; i++)
835 r =
r ^ std::hash<T>{}(begin[i]);
837 for (ptrdiff_t i = 0; i < size; i++)
841 auto *start =
reinterpret_cast<uint8_t *
>(&(*begin));
842 for (
size_t i = 0; i < size *
sizeof(T); i++)
843 r =
r ^ std::hash<uint8_t>{}(start[i]);
850 template <
typename T, std::
size_t s>
858 r =
r ^ std::hash<decltype(i)>()(i);
869 constexpr std::string_view
Red =
"\033[91m";
871 constexpr std::string_view
Green =
"\033[92m";
873 constexpr std::string_view
Yellow =
"\033[93m";
875 constexpr std::string_view
Blue =
"\033[94m";
877 constexpr std::string_view
Magenta =
"\033[95m";
879 constexpr std::string_view
Cyan =
"\033[96m";
881 constexpr std::string_view
White =
"\033[97m";
883 constexpr std::string_view
Reset =
"\033[0m";
885 constexpr std::string_view
Bold =
"\033[1m";
889 constexpr std::string_view
Blink =
"\033[5m";
891 constexpr std::string_view
Reverse =
"\033[7m";
893 constexpr std::string_view
Hidden =
"\033[8m";
968# define DNDS_RESTRICT __restrict
970# define DNDS_FORCEINLINE __forceinline
971#elif defined(__GNUC__) || defined(__clang__)
973# define DNDS_RESTRICT __restrict__
975# define DNDS_FORCEINLINE inline __attribute__((always_inline))
977# define DNDS_RESTRICT
978# define DNDS_FORCEINLINE
void DNDS_signal_handler(int signal)
#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE(T, T_Self)
#define DNDS_DEVICE_CALLABLE
void DNDS_signal_handler(int signal)
Pre-compiled-header style shim that includes the heavy Eigen headers under DNDSR's warning suppressio...
Assertion / error-handling macros and supporting helper functions.
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
Project-wide preprocessor flags, branch-hint macros, and version/build metadata strings....
Mixin base class providing a runtime instance name for tracing/debugging.
std::string getObjectIdentity(const std::string &sig) const
ObjectNaming(ObjectNaming &&)=default
ObjectNaming & operator=(ObjectNaming &&)=default
ObjectNaming & operator=(const ObjectNaming &)=default
const std::string & getObjectName() const
ObjectNaming(const ObjectNaming &)=default
void setObjectName(const std::string &name)
constexpr std::string_view Blue
ANSI escape: bright blue foreground.
constexpr std::string_view Blink
ANSI escape: blinking text.
constexpr std::string_view Cyan
ANSI escape: bright cyan foreground.
constexpr std::string_view Magenta
ANSI escape: bright magenta foreground.
constexpr std::string_view Reverse
ANSI escape: reverse (swap fg/bg).
constexpr std::string_view White
ANSI escape: bright white foreground.
constexpr std::string_view Reset
ANSI escape: reset all attributes.
constexpr std::string_view Green
ANSI escape: bright green foreground.
constexpr std::string_view Yellow
ANSI escape: bright yellow foreground.
constexpr std::string_view Red
ANSI escape: bright red foreground.
constexpr std::string_view Bold
ANSI escape: bold.
constexpr std::string_view Underline
ANSI escape: underline.
constexpr std::string_view Hidden
ANSI escape: hidden text.
the host side operators are provided as implemented
constexpr T cube(const T &a)
a * a * a, constexpr.
bool signedIntWillAddOverflow(T value, T increment)
Overflow-detecting test for value + increment on signed integers.
std::vector< rowsize > t_RowsizeVec
Vector of row widths (one rowsize per row).
int32_t real_half_sized_index
Integer type with half the width of real.
ssp< std::ostream > logStream
Shared output stream: where DNDS::log() writes progress / diagnostics.
void PrintVec(const std::vector< T > &dat, std::ostream &out)
Print a vector to out with outputDelim between elements.
constexpr real signM(real a)
"Signum, biased toward -1": treats 0 as negative.
int get_env_OMP_NUM_THREADS()
Read OMP_NUM_THREADS env var, returning 1 if unset / invalid.
DNDS_CONSTANT const index UnInitIndex
Sentinel "not initialised" index value (= INT64_MIN).
rowsize size_to_rowsize(size_t v)
Range-checked conversion from size_t to DNDS::rowsize.
bool sstringHasSuffix(const std::string &str, const std::string &suffix)
int32_t checkedIndexTo32(index v)
Narrow index to int32_t with range check; dies on overflow.
DNDS_CONSTANT const rowsize NoAlign
Alignment flag: no padding applied to rows (the only currently-supported value).
DNDS_CONSTANT const real verySmallReal
Catch-all lower bound ("effectively zero").
constexpr int RowSize_To_EigenSize(rowsize rs)
Convert a rowsize constant to the corresponding Eigen compile-time size. Fixed >= 0 -> the value; Dyn...
T size_t_to_signed(size_t v)
Narrowing size_t -> T conversion with range check.
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
Convenience remove_cv + remove_reference composition (C++17 port of C++20's std::remove_cvref_t).
int64_t real_sized_index
Integer type with the same width as real (used for type-punning / packing).
void RegisterSignalHandler()
Install SEGV / ABRT handlers that print a backtrace via DNDS_signal_handler.
int32_t rowsize
Row-width / per-row element-count type (signed 32-bit).
DNDS_CONSTANT const real pi
π in double precision (matches DNDS_E_PI macro).
constexpr real signTol(real a, real tol)
Tolerant signum: returns 0 inside [-tol, tol].
DNDS_CONSTANT const rowsize DynamicSize
Template parameter flag: "row width is set at runtime but uniform".
DNDS_CONSTANT const real UnInitReal
Sentinel "not initialised" real value (NaN). Cheap to detect with std::isnan or IsUnInitReal; survive...
void AccumulateRowSize(const TtRowsizeVec &rowsizes, TtIndexVec &rowstarts)
Build a prefix-sum table from a row-size vector.
constexpr T divide_ceil(T a, T b)
Integer ceiling division ceil(a / b). Correct for all signs.
constexpr auto divCeil(TL l, TR r)
Integer ceiling division. l must be non-negative, r positive.
constexpr real sign(real a)
Signum function: +1, 0, or -1.
DNDS_CONSTANT const rowsize NonUniformSize
Template parameter flag: "each row has an independent width".
std::pair< index, index > EvenSplitRange(int rank, int nRanks, index nGlobal)
Split a global range [0, nGlobal) evenly among nRanks workers.
void setLogStream(ssp< std::ostream > nstream)
Redirect log() output to a user-supplied stream. Ownership is shared.
std::string RowSize_To_PySnippet(rowsize rs)
Encode a rowsize constant as a short Python-binding snippet: "<number>" for fixed,...
std::vector< index > t_IndexVec
Vector of index values (global offsets, local ids, etc.).
bool checkUniformVector(const std::vector< T > &dat, T &value)
Whether all elements of dat are equal; if so, stores the value into value.
std::tuple< index, index > t_indexerPair
Paired indices, typically (start, size) or (first, last).
std::vector< std::string > splitSString(const std::string &str, char delim)
bool logIsTTY()
Convenience: ostreamIsTTY applied to the current log() stream.
T signedIntSafeAdd(T value, T increment)
Add two signed integers, asserting on overflow instead of silently wrapping.
Eigen::Matrix< real, Eigen::Dynamic, Eigen::Dynamic > MatrixXR
Column-major dynamic Eigen matrix of reals (default layout).
int get_terminal_width()
Terminal width in columns (falls back to a fixed default when not a TTY).
index size_to_index(size_t v)
Range-checked conversion from size_t to DNDS::index.
bool IsUnInitReal(real v)
Whether v equals the NaN sentinel UnInitReal (tested via isnan).
DNDS_CONSTANT const real largeReal
Loose upper bound (e.g., for non-dimensional limits).
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
constexpr T mod(T a, T b)
Mathematical modulo that always returns a non-negative result. Unlike % in C++ where (-1) % 3 == -1,...
std::string getStringForcePath(const std::filesystem::path::string_type &v)
Portable conversion of a platform-native path string to std::string.
std::string getStringForceWString(const std::wstring &v)
Convert a wstring to string (UTF-8 on Windows, byte-cast elsewhere).
constexpr T sqr(const T &a)
a * a, constexpr. Works for all arithmetic types.
Eigen::RowVector< real, Eigen::Dynamic > RowVectorXR
Dynamic row-vector of reals.
Eigen::Matrix< real, -1, -1, Eigen::RowMajor > tDiFj
Row-major dynamic Eigen matrix used by quadrature / basis tables.
int get_env_DNDS_DIST_OMP_NUM_THREADS()
Read the DNDSR-specific DNDS_DIST_OMP_NUM_THREADS override, falling back to get_env_OMP_NUM_THREADS.
std::shared_ptr< T > ssp
Shortened alias for std::shared_ptr used pervasively in DNDSR.
DNDS_CONSTANT const index indexMin
Minimum representable index value (= INT64_MIN).
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
constexpr real signP(real a)
"Signum, biased toward +1": treats 0 as positive.
ssp< T > make_ssp(Args &&...args)
Type-safe replacement for DNDS_MAKE_SSP. Creates ssp<T> with forwarded args.
bool ostreamIsTTY(std::ostream &ostream)
Heuristic detection of whether ostream is attached to a terminal.
ssp< t_IndexVec > t_pIndexVec
Shared pointer alias to t_IndexVec (used by mapping tables shared between arrays, see IndexMapping....
std::vector< std::string > splitSStringClean(const std::string &str, char delim)
void print_progress(std::ostream &os, double progress)
Render a textual progress bar to os for progress in [0, 1].
real float_mod(real a, real b)
Floating-point modulo matching Python's % (result has sign of b).
std::string Align_To_PySnippet(rowsize al)
Encode an alignment value as a Python-binding snippet: "N" for NoAlign, the number otherwise.
DNDS_CONSTANT const real smallReal
Loose lower bound (for iterative-solver tolerances etc.).
Eigen::Vector< real, Eigen::Dynamic > VectorXR
Dynamic Eigen vector of reals.
std::ostream & log()
Return the current DNDSR log stream (either std::cout or the installed file).
bool iterateIdentical(tIt1 it1, tIt1end it1end, tIt2 it2, tIt2end it2end, tF F)
Walk two ordered ranges in lockstep, calling F on each match.
DNDS_CONSTANT const real veryLargeReal
Catch-all upper bound ("practically infinity") for physical scalars.
bool useCout
Whether DNDS::log() is currently routed to std::cout.
void setLogStreamCout()
Restore the default std::cout routing for log().
std::string GetSetVersionName(const std::string &ver)
Read/set the build version string accessible from code.
DNDS_CONSTANT const rowsize UnInitRowsize
Sentinel "not initialised" rowsize value (= INT32_MIN).
Empty placeholder type without a default constructor; accepts any assignment.
DNDS_DEVICE_CALLABLE EmptyNoDefault(EmptyNoDefault &&v)=default
DNDS_DEVICE_CALLABLE EmptyNoDefault(const EmptyNoDefault &v)=default
DNDS_DEVICE_CALLABLE EmptyNoDefault & operator=(T v)
DNDS_DEVICE_CALLABLE EmptyNoDefault(T v)
DNDS_DEVICE_CALLABLE EmptyNoDefault & operator=(const EmptyNoDefault &)=default
Trivially-copyable empty placeholder type that accepts any assignment.
DNDS_DEVICE_CALLABLE Empty & operator=(T v)
DNDS_DEVICE_CALLABLE Empty(T v)
Tag type for naming objects created via make_ssp.
Hash functor for std::array<T, s>, combining element hashes via XOR.
std::size_t operator()(const std::array< T, s > &v) const noexcept
Type trait that detects whether a type is a std::shared_ptr wrapping.
Hash functor for std::vector<T>, combining element hashes via XOR.
std::size_t operator()(const std::vector< T > &v) const noexcept
std::size_t operator()(TBegin &&begin, TEnd &&end) const noexcept
Eigen::Matrix< real, 5, 1 > v