morton-arithmetic 0.1.0
Fast Morton (Z-order) codes with O(1) arithmetic
Loading...
Searching...
No Matches
batch.hpp
Go to the documentation of this file.
1
15
16#ifndef MORTON_BATCH_HPP
17#define MORTON_BATCH_HPP
18
19#include <cstddef>
20#include <cstdint>
21#include <type_traits>
22
23#include "morton/morton.hpp"
24#include "morton/simd.hpp"
25
26namespace morton {
27namespace batch {
28
31template <unsigned Dim, unsigned Bits>
32void add(const typename Morton<Dim, Bits>::code_type* in,
33 typename Morton<Dim, Bits>::code_type* out, std::size_t n, unsigned axis,
35 using M = Morton<Dim, Bits>;
36 using code = typename M::code_type;
37 const code mask = M::axis_mask(axis);
38 const code notM = code(~mask);
39 const code keep = M::field_mask & notM;
40 const code dk = M::deposit(k, axis); // loop-invariant
41#if MORTON_X86
42 if constexpr (std::is_same_v<code, std::uint64_t>) {
43 if (detail::cpu_has_avx512f()) {
44 detail::avx512::add64(in, out, n, notM, dk, mask, keep);
45 return;
46 }
47 }
48#endif
49 for (std::size_t i = 0; i < n; ++i) {
50 code c = in[i];
51 out[i] = code((c | notM) + dk) & mask;
52 out[i] |= c & keep;
53 }
54}
55
57template <unsigned Dim, unsigned Bits>
58void sub(const typename Morton<Dim, Bits>::code_type* in,
59 typename Morton<Dim, Bits>::code_type* out, std::size_t n, unsigned axis,
61 using M = Morton<Dim, Bits>;
62 using code = typename M::code_type;
63 const code mask = M::axis_mask(axis);
64 const code keep = M::field_mask & code(~mask);
65 const code dk = M::deposit(k, axis);
66#if MORTON_X86
67 if constexpr (std::is_same_v<code, std::uint64_t>) {
68 if (detail::cpu_has_avx512f()) {
69 detail::avx512::sub64(in, out, n, dk, mask, keep);
70 return;
71 }
72 }
73#endif
74 for (std::size_t i = 0; i < n; ++i) {
75 code c = in[i];
76 out[i] = (code((c & mask) - dk) & mask) | (c & keep);
77 }
78}
79
81template <unsigned Dim, unsigned Bits>
82void step(const typename Morton<Dim, Bits>::code_type* in,
83 typename Morton<Dim, Bits>::code_type* out, std::size_t n, unsigned axis, int dir) {
84 if (dir >= 0)
85 add<Dim, Bits>(in, out, n, axis, 1);
86 else
87 sub<Dim, Bits>(in, out, n, axis, 1);
88}
89
91template <unsigned Bits>
93 const typename Morton<2, Bits>::coord_type* y,
94 typename Morton<2, Bits>::code_type* out, std::size_t n) {
95 using M = Morton<2, Bits>;
96#if MORTON_X86
97 if constexpr (Bits == 32) { // coord_type == uint32, code_type == uint64
98 if (detail::cpu_has_avx512f()) {
99 detail::avx512::encode2(x, y, out, n);
100 return;
101 }
102 }
103#endif
104 for (std::size_t i = 0; i < n; ++i)
105 out[i] = M::encode(x[i], y[i]).code();
106}
107
109template <unsigned Bits>
111 const typename Morton<3, Bits>::coord_type* y,
112 const typename Morton<3, Bits>::coord_type* z,
113 typename Morton<3, Bits>::code_type* out, std::size_t n) {
114 using M = Morton<3, Bits>;
115#if MORTON_X86
116 if constexpr (Bits == 21) { // coord_type == uint32, code_type == uint64
117 if (detail::cpu_has_avx512f()) {
118 detail::avx512::encode3(x, y, z, out, n);
119 return;
120 }
121 }
122#endif
123 for (std::size_t i = 0; i < n; ++i)
124 out[i] = M::encode(x[i], y[i], z[i]).code();
125}
126
128template <unsigned Bits>
130 typename Morton<2, Bits>::coord_type* y, std::size_t n) {
131 using M = Morton<2, Bits>;
132#if MORTON_X86
133 if constexpr (Bits == 32) {
134 if (detail::cpu_has_avx512f()) {
135 detail::avx512::decode2(in, x, y, n);
136 return;
137 }
138 }
139#endif
140 for (std::size_t i = 0; i < n; ++i) {
141 auto a = M::from_code(in[i]).decode();
142 x[i] = a[0];
143 y[i] = a[1];
144 }
145}
146
148template <unsigned Bits>
151 std::size_t n) {
152 using M = Morton<3, Bits>;
153#if MORTON_X86
154 if constexpr (Bits == 21) {
155 if (detail::cpu_has_avx512f()) {
156 detail::avx512::decode3(in, x, y, z, n);
157 return;
158 }
159 }
160#endif
161 for (std::size_t i = 0; i < n; ++i) {
162 auto a = M::from_code(in[i]).decode();
163 x[i] = a[0];
164 y[i] = a[1];
165 z[i] = a[2];
166 }
167}
168
169} // namespace batch
170} // namespace morton
171
172#endif // MORTON_BATCH_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.
void decode2(const typename Morton< 2, Bits >::code_type *in, typename Morton< 2, Bits >::coord_type *x, typename Morton< 2, Bits >::coord_type *y, std::size_t n)
Decode an array of codes back to coordinate arrays (2D).
Definition batch.hpp:129
void encode3(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)
Encode arrays of coordinates (3D) into codes.
Definition batch.hpp:110
void sub(const typename Morton< Dim, Bits >::code_type *in, typename Morton< Dim, Bits >::code_type *out, std::size_t n, unsigned axis, typename Morton< Dim, Bits >::coord_type k)
Subtract the same k from axis of every code (wraps). Vectorised.
Definition batch.hpp:58
void encode2(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)
Encode arrays of coordinates (2D) into codes.
Definition batch.hpp:92
void add(const typename Morton< Dim, Bits >::code_type *in, typename Morton< Dim, Bits >::code_type *out, std::size_t n, unsigned axis, typename Morton< Dim, Bits >::coord_type k)
Add the same k to axis of every code (wraps).
Definition batch.hpp:32
void decode3(const typename Morton< 3, Bits >::code_type *in, 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)
Decode an array of codes back to coordinate arrays (3D).
Definition batch.hpp:149
void step(const typename Morton< Dim, Bits >::code_type *in, typename Morton< Dim, Bits >::code_type *out, std::size_t n, unsigned axis, int dir)
Step every code one cell along ±axis (dir>=0 -> +1, else -1). Vectorised.
Definition batch.hpp:82
Definition batch.hpp:26
Explicit AVX-512 batch kernels for the bulk encode/decode/arithmetic paths.