core 1.5.0
Shared MPI block decomposition, asynchronous ghost-layer exchange, SDF geometry, load balancing (header-only C++20)
Loading...
Searching...
No Matches
portable.hpp
Go to the documentation of this file.
1// core — host/device portability shim for the shared geometry layer.
2//
3// Two things live here, both required by peclet/core/geom/primitives.hpp:
4//
5// PECLET_HD — the host+device function annotation. Three branches, copied from morton's
6// MORTON_HD (morton/include/morton/hd.hpp): Kokkos when Kokkos is in the
7// translation unit, raw __host__ __device__ under nvcc/hipcc, nothing otherwise.
8// The nvcc/hipcc branch is what makes the include order forgiving: a Kokkos+CUDA
9// build compiles through nvcc, so even a TU that reaches this header before
10// Kokkos_Core.hpp still gets a device-callable annotation. Wrapped in
11// `#if !defined(PECLET_HD)` so a build can override it.
12//
13// Vec3<Real> — a Real-templated POD 3-vector, plus the small vector/quaternion algebra the
14// scene transform stack needs. Deliberately NOT peclet::core::Vec<3>, which is
15// std::array<Real, 3> with `Real` a fixed double typedef (common/types.hpp):
16// neither Real-templated nor a natural device type. Vec3 is what dem's F3 becomes
17// and what voro's loose `Real x, y, z` parameters collapse into. Bundling the
18// algebra here mirrors how dem organises the same material (F3 ships alongside
19// add3/sub3/scale3/dot3/len3/cross3v/rotateVector in dem_portable.hpp), so the
20// rung-3 port is a rename rather than a rewrite.
21//
22// C++17-clean (no concepts, no C++20 constructs) so it can be pulled into CUDA translation units,
23// matching the pledge in common/types.hpp. Design: suite/docs/ANALYTIC_SDF_GEOMETRY.md.
24#ifndef PECLET_CORE_COMMON_PORTABLE_HPP
25#define PECLET_CORE_COMMON_PORTABLE_HPP
26
27#if !defined(PECLET_HD)
28#if defined(KOKKOS_VERSION)
29// KOKKOS_INLINE_FUNCTION (not KOKKOS_FUNCTION as in morton): these are header-only templates that
30// must inline.
31#define PECLET_HD KOKKOS_INLINE_FUNCTION
32#elif defined(__CUDACC__) || defined(__HIPCC__)
33#define PECLET_HD __host__ __device__ inline
34#else
35#define PECLET_HD inline
36#endif
37#endif // !defined(PECLET_HD)
38
39#include <cmath>
40
41namespace peclet::core {
42
44template <class Real>
45struct Vec3 {
46 Real x, y, z;
47};
48
50template <class Real>
51struct Quat {
52 Real x, y, z, w;
53};
54
55// --- vector algebra (association order transcribed from dem's math_utils heritage) -------------
56
57template <class Real>
59 return Vec3<Real>{a.x + b.x, a.y + b.y, a.z + b.z};
60}
61template <class Real>
63 return Vec3<Real>{a.x - b.x, a.y - b.y, a.z - b.z};
64}
65template <class Real>
67 return Vec3<Real>{a.x * s, a.y * s, a.z * s};
68}
69template <class Real>
71 return a.x * b.x + a.y * b.y + a.z * b.z;
72}
73template <class Real>
75 return Vec3<Real>{a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
76}
77
80template <class Real>
82 const Vec3<Real> qv{q.x, q.y, q.z};
83 const Vec3<Real> t = scale(cross(qv, v), Real(2));
84 return add(add(v, scale(t, q.w)), cross(qv, t));
85}
86
88template <class Real>
90 return rotate(Quat<Real>{-q.x, -q.y, -q.z, q.w}, v);
91}
92
95template <class Real>
97 return Quat<Real>{
98 a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y, a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
99 a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w, a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
100}
101
102namespace detail {
103
104// Math shims. When Kokkos is present the geometry MUST route through Kokkos::* so the formulas are
105// bit-identical to dem's originals (dem_portable.hpp uses Kokkos::sqrt/fabs/fmax/fmin throughout);
106// on a host-only core build there is no Kokkos, so std::* stands in. Both map to the same libm
107// call on host, which is what keeps the bit-exactness gate meaningful in either build.
108#if defined(KOKKOS_VERSION)
109template <class Real>
111 return Kokkos::sqrt(v);
112}
113template <class Real>
115 return Kokkos::fabs(v);
116}
117template <class Real>
119 return Kokkos::fmax(a, b);
120}
121template <class Real>
123 return Kokkos::fmin(a, b);
124}
125template <class Real>
127 return Kokkos::pow(a, b);
128}
129template <class Real>
131 return Kokkos::nearbyint(v);
132}
133template <class Real>
135 return Kokkos::floor(v);
136}
137template <class Real>
138PECLET_HD Real hdFma(Real a, Real b, Real c) {
139 return Kokkos::fma(a, b, c);
140}
141#else
142template <class Real>
144 return std::sqrt(v);
145}
146template <class Real>
148 return std::fabs(v);
149}
150template <class Real>
152 return std::fmax(a, b);
153}
154template <class Real>
156 return std::fmin(a, b);
157}
158template <class Real>
160 return std::pow(a, b);
161}
162template <class Real>
164 return std::nearbyint(v);
165}
166template <class Real>
168 return std::floor(v);
169}
170template <class Real>
172 return std::fma(a, b, c);
173}
174#endif
175
179template <class Real>
181 return (a < b) ? b : a;
182}
183
184} // namespace detail
185} // namespace peclet::core
186
187#endif // PECLET_CORE_COMMON_PORTABLE_HPP
PECLET_HD Real hdMin(Real a, Real b)
Definition portable.hpp:155
PECLET_HD Real hdPow(Real a, Real b)
Definition portable.hpp:159
PECLET_HD Real cmpMax(Real a, Real b)
Comparison-based max, <-ordered (ties keep the earlier operand) — std::max semantics,...
Definition portable.hpp:180
PECLET_HD Real hdFma(Real a, Real b, Real c)
Definition portable.hpp:171
PECLET_HD Real hdMax(Real a, Real b)
Definition portable.hpp:151
PECLET_HD Real hdFloor(Real v)
Definition portable.hpp:167
PECLET_HD Real hdNearbyint(Real v)
Definition portable.hpp:163
PECLET_HD Real hdAbs(Real v)
Definition portable.hpp:147
PECLET_HD Real hdSqrt(Real v)
Definition portable.hpp:143
PECLET_HD Quat< Real > mulQuat(Quat< Real > a, Quat< Real > b)
Hamilton product a ⊗ b in the (x, y, z, w) storage convention rotate uses, so rotate(mulQuat(a,...
Definition portable.hpp:96
PECLET_HD Vec3< Real > rotate(Quat< Real > q, Vec3< Real > v)
Rotate v by q.
Definition portable.hpp:81
PECLET_HD Vec3< Real > add(Vec3< Real > a, Vec3< Real > b)
Definition portable.hpp:58
PECLET_HD Real dot(Vec3< Real > a, Vec3< Real > b)
Definition portable.hpp:70
PECLET_HD Vec3< Real > invRotate(Quat< Real > q, Vec3< Real > v)
Rotate v by the conjugate of q — dem invRotateVector.
Definition portable.hpp:89
PECLET_HD Vec3< Real > sub(Vec3< Real > a, Vec3< Real > b)
Definition portable.hpp:62
PECLET_HD Vec3< Real > scale(Vec3< Real > a, Real s)
Definition portable.hpp:66
PECLET_HD Vec3< Real > cross(Vec3< Real > a, Vec3< Real > b)
Definition portable.hpp:74
double Real
Default host floating type. Device kernels may use float; conversions happen at the boundary.
Definition types.hpp:18
#define PECLET_HD
Definition portable.hpp:35
Quaternion, {x, y, z, w} — dem's F4 ordering (dem_portable.hpp), NOT {w, x, y, z}.
Definition portable.hpp:51
Real-templated POD 3-vector — the geometry layer's point type on host and device.
Definition portable.hpp:45