morton-arithmetic 0.1.0
Fast Morton (Z-order) codes with O(1) arithmetic
Loading...
Searching...
No Matches
kokkos.hpp
Go to the documentation of this file.
1
23
24#ifndef MORTON_KOKKOS_HPP
25#define MORTON_KOKKOS_HPP
26
27#if !defined(MORTON_ENABLE_KOKKOS)
28#error "morton/kokkos.hpp requires MORTON_ENABLE_KOKKOS (configure with -DMORTON_ENABLE_KOKKOS=ON)"
29#endif
30
31#include <cstddef>
32#include <Kokkos_Core.hpp> // must precede morton.hpp so KOKKOS_VERSION drives MORTON_HD
33
34#include "morton/morton.hpp"
35
36namespace morton {
37namespace kokkos {
38
39namespace detail {
40// Unmanaged host view over a raw caller pointer, for staging to/from device.
41template <class T>
42using host_ptr_view = Kokkos::View<T*, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
43} // namespace detail
44
45// ---------------------------------------------------------------------------
46// View-based API (caller owns the Views; execution space deduced from `out`)
47// ---------------------------------------------------------------------------
48
50template <unsigned Bits, class ViewX, class ViewY, class ViewOut>
51void encode2(const ViewX& x, const ViewY& y, const ViewOut& out) {
52 using M = Morton<2, Bits>;
53 using exec = typename ViewOut::execution_space;
54 const std::size_t n = out.extent(0);
55 Kokkos::parallel_for(
56 "morton::kokkos::encode2", Kokkos::RangePolicy<exec>(0, n),
57 KOKKOS_LAMBDA(const std::size_t i) { out(i) = M::encode(x(i), y(i)).code(); });
58}
59
61template <unsigned Bits, class ViewX, class ViewY, class ViewZ, class ViewOut>
62void encode3(const ViewX& x, const ViewY& y, const ViewZ& z, const ViewOut& out) {
63 using M = Morton<3, Bits>;
64 using exec = typename ViewOut::execution_space;
65 const std::size_t n = out.extent(0);
66 Kokkos::parallel_for(
67 "morton::kokkos::encode3", Kokkos::RangePolicy<exec>(0, n),
68 KOKKOS_LAMBDA(const std::size_t i) { out(i) = M::encode(x(i), y(i), z(i)).code(); });
69}
70
72template <unsigned Bits, class ViewCode, class ViewX, class ViewY>
73void decode2(const ViewCode& code, const ViewX& x, const ViewY& y) {
74 using M = Morton<2, Bits>;
75 using exec = typename ViewCode::execution_space;
76 const std::size_t n = code.extent(0);
77 Kokkos::parallel_for(
78 "morton::kokkos::decode2", Kokkos::RangePolicy<exec>(0, n),
79 KOKKOS_LAMBDA(const std::size_t i) {
80 M m = M::from_code(code(i));
81 x(i) = m.get(0);
82 y(i) = m.get(1);
83 });
84}
85
87template <unsigned Bits, class ViewCode, class ViewX, class ViewY, class ViewZ>
88void decode3(const ViewCode& code, const ViewX& x, const ViewY& y, const ViewZ& z) {
89 using M = Morton<3, Bits>;
90 using exec = typename ViewCode::execution_space;
91 const std::size_t n = code.extent(0);
92 Kokkos::parallel_for(
93 "morton::kokkos::decode3", Kokkos::RangePolicy<exec>(0, n),
94 KOKKOS_LAMBDA(const std::size_t i) {
95 M m = M::from_code(code(i));
96 x(i) = m.get(0);
97 y(i) = m.get(1);
98 z(i) = m.get(2);
99 });
100}
101
104template <unsigned Dim, unsigned Bits, class ViewIn, class ViewOut>
105void add(const ViewIn& in, const ViewOut& out, unsigned axis, long long delta) {
106 using M = Morton<Dim, Bits>;
107 using C = typename M::coord_type;
108 using exec = typename ViewOut::execution_space;
109 const std::size_t n = out.extent(0);
110 const bool neg = delta < 0;
111 const C mag =
112 neg ? C(static_cast<unsigned long long>(-delta)) : C(static_cast<unsigned long long>(delta));
113 Kokkos::parallel_for(
114 "morton::kokkos::add", Kokkos::RangePolicy<exec>(0, n), KOKKOS_LAMBDA(const std::size_t i) {
115 M m = M::from_code(in(i));
116 if (neg)
117 m.sub(axis, mag);
118 else
119 m.add(axis, mag);
120 out(i) = m.code();
121 });
122}
123
125template <unsigned Dim, unsigned Bits, class ViewIn, class ViewOut>
126void sub(const ViewIn& in, const ViewOut& out, unsigned axis,
128 add<Dim, Bits>(in, out, axis, -static_cast<long long>(k));
129}
130
132template <unsigned Dim, unsigned Bits, class ViewIn, class ViewOut>
133void step(const ViewIn& in, const ViewOut& out, unsigned axis, int dir) {
134 add<Dim, Bits>(in, out, axis, dir >= 0 ? 1 : -1);
135}
136
137// ---------------------------------------------------------------------------
138// Host-pointer convenience API (stage to device Views, run, copy back)
139// ---------------------------------------------------------------------------
140
141template <unsigned Bits>
143 const typename Morton<2, Bits>::coord_type* y,
144 typename Morton<2, Bits>::code_type* out, std::size_t n) {
145 using C = typename Morton<2, Bits>::coord_type;
146 using K = typename Morton<2, Bits>::code_type;
147 Kokkos::View<C*> dx("morton.x", n), dy("morton.y", n);
148 Kokkos::View<K*> dout("morton.out", n);
149 Kokkos::deep_copy(dx, detail::host_ptr_view<const C>(x, n));
150 Kokkos::deep_copy(dy, detail::host_ptr_view<const C>(y, n));
152 Kokkos::deep_copy(detail::host_ptr_view<K>(out, n), dout);
153}
154
155template <unsigned Bits>
157 const typename Morton<3, Bits>::coord_type* y,
158 const typename Morton<3, Bits>::coord_type* z,
159 typename Morton<3, Bits>::code_type* out, std::size_t n) {
160 using C = typename Morton<3, Bits>::coord_type;
161 using K = typename Morton<3, Bits>::code_type;
162 Kokkos::View<C*> dx("morton.x", n), dy("morton.y", n), dz("morton.z", n);
163 Kokkos::View<K*> dout("morton.out", n);
164 Kokkos::deep_copy(dx, detail::host_ptr_view<const C>(x, n));
165 Kokkos::deep_copy(dy, detail::host_ptr_view<const C>(y, n));
166 Kokkos::deep_copy(dz, detail::host_ptr_view<const C>(z, n));
168 Kokkos::deep_copy(detail::host_ptr_view<K>(out, n), dout);
169}
170
171template <unsigned Bits>
172void decode2_host(const typename Morton<2, Bits>::code_type* code,
174 std::size_t n) {
175 using C = typename Morton<2, Bits>::coord_type;
176 using K = typename Morton<2, Bits>::code_type;
177 Kokkos::View<K*> dcode("morton.code", n);
178 Kokkos::View<C*> dx("morton.x", n), dy("morton.y", n);
179 Kokkos::deep_copy(dcode, detail::host_ptr_view<const K>(code, n));
181 Kokkos::deep_copy(detail::host_ptr_view<C>(x, n), dx);
182 Kokkos::deep_copy(detail::host_ptr_view<C>(y, n), dy);
183}
184
185template <unsigned Bits>
186void decode3_host(const typename Morton<3, Bits>::code_type* code,
188 typename Morton<3, Bits>::coord_type* z, std::size_t n) {
189 using C = typename Morton<3, Bits>::coord_type;
190 using K = typename Morton<3, Bits>::code_type;
191 Kokkos::View<K*> dcode("morton.code", n);
192 Kokkos::View<C*> dx("morton.x", n), dy("morton.y", n), dz("morton.z", n);
193 Kokkos::deep_copy(dcode, detail::host_ptr_view<const K>(code, n));
195 Kokkos::deep_copy(detail::host_ptr_view<C>(x, n), dx);
196 Kokkos::deep_copy(detail::host_ptr_view<C>(y, n), dy);
197 Kokkos::deep_copy(detail::host_ptr_view<C>(z, n), dz);
198}
199
200template <unsigned Dim, unsigned Bits>
202 typename Morton<Dim, Bits>::code_type* out, std::size_t n, unsigned axis,
203 long long delta) {
204 using K = typename Morton<Dim, Bits>::code_type;
205 Kokkos::View<K*> din("morton.in", n), dout("morton.out", n);
206 Kokkos::deep_copy(din, detail::host_ptr_view<const K>(in, n));
208 Kokkos::deep_copy(detail::host_ptr_view<K>(out, n), dout);
209}
210
211} // namespace kokkos
212} // namespace morton
213
214#endif // MORTON_KOKKOS_HPP
A Morton (Z-order) code interleaving Dim unsigned coordinates of Bits bits each.
Definition morton.hpp:203
detail::uint_for_t< Bits > coord_type
Definition morton.hpp:215
detail::uint_for_t< Dim *Bits > code_type
Definition morton.hpp:214
Core Morton<Dim,Bits> type — Z-order codes with O(1) arithmetic in Morton space.
Kokkos::View< T *, Kokkos::HostSpace, Kokkos::MemoryTraits< Kokkos::Unmanaged > > host_ptr_view
Definition kokkos.hpp:42
void decode3_host(const typename Morton< 3, Bits >::code_type *code, typename Morton< 3, Bits >::coord_type *x, typename Morton< 3, Bits >::coord_type *y, typename Morton< 3, Bits >::coord_type *z, std::size_t n)
Definition kokkos.hpp:186
void decode2(const ViewCode &code, const ViewX &x, const ViewY &y)
Decode a code View back to coordinate Views (2D).
Definition kokkos.hpp:73
void decode2_host(const typename Morton< 2, Bits >::code_type *code, typename Morton< 2, Bits >::coord_type *x, typename Morton< 2, Bits >::coord_type *y, std::size_t n)
Definition kokkos.hpp:172
void add(const ViewIn &in, const ViewOut &out, unsigned axis, long long delta)
Add a signed delta to axis of every code (wraps mod 2^Bits).
Definition kokkos.hpp:105
void step(const ViewIn &in, const ViewOut &out, unsigned axis, int dir)
Step every code one cell along ±axis (dir>=0 -> +1, else -1).
Definition kokkos.hpp:133
void sub(const ViewIn &in, const ViewOut &out, unsigned axis, typename Morton< Dim, Bits >::coord_type k)
Subtract k from axis of every code (wraps). Convenience over add.
Definition kokkos.hpp:126
void encode3_host(const typename Morton< 3, Bits >::coord_type *x, const typename Morton< 3, Bits >::coord_type *y, const typename Morton< 3, Bits >::coord_type *z, typename Morton< 3, Bits >::code_type *out, std::size_t n)
Definition kokkos.hpp:156
void decode3(const ViewCode &code, const ViewX &x, const ViewY &y, const ViewZ &z)
Decode a code View back to coordinate Views (3D).
Definition kokkos.hpp:88
void encode2_host(const typename Morton< 2, Bits >::coord_type *x, const typename Morton< 2, Bits >::coord_type *y, typename Morton< 2, Bits >::code_type *out, std::size_t n)
Definition kokkos.hpp:142
void encode2(const ViewX &x, const ViewY &y, const ViewOut &out)
Encode coordinate Views (2D) into a code View. x,y,out extents must match.
Definition kokkos.hpp:51
void add_host(const typename Morton< Dim, Bits >::code_type *in, typename Morton< Dim, Bits >::code_type *out, std::size_t n, unsigned axis, long long delta)
Definition kokkos.hpp:201
void encode3(const ViewX &x, const ViewY &y, const ViewZ &z, const ViewOut &out)
Encode coordinate Views (3D) into a code View.
Definition kokkos.hpp:62
Definition batch.hpp:26