Block-Structured AMR Software Framework
AMReX_Morton.H
Go to the documentation of this file.
1 #ifndef AMREX_MORTON_H_
2 #define AMREX_MORTON_H_
3 #include <AMReX_Config.H>
4 
5 #include <AMReX_REAL.H>
6 #include <AMReX_Dim3.H>
7 #include <AMReX_Array.H>
8 #include <AMReX_GpuQualifiers.H>
9 
10 #include <cstdint>
11 
12 namespace amrex::Morton {
13 
31 std::uint32_t makeSpace (std::uint32_t x) noexcept {
32 #if (AMREX_SPACEDIM == 3)
33  // x : 0000,0000,0000,0000,0000,00a9,8765,4321
34  x = (x | (x << 16)) & 0x030000FF;
35  // x << 16 : 0000,00a9,8765,4321,0000,0000,0000,0000
36  // x | (x << 16): 0000,00a9,8765,4321,0000,00a9,8765,4321
37  // 0x030000FF : 0000,0011,0000,0000,0000,0000,1111,1111
38  // x : 0000,00a9,0000,0000,0000,0000,8765,4321
39  x = (x | (x << 8)) & 0x0300F00F;
40  // x << 8 : 0000,0000,0000,0000,8765,4321,0000,0000
41  // x | (x << 8) : 0000,00a9,0000,0000,8765,4321,8765,4321
42  // 0x0300F00F : 0000,0011,0000,0000,1111,0000,0000,1111
43  // x : 0000,00a9,0000,0000,8765,0000,0000,4321
44  x = (x | (x << 4)) & 0x030C30C3;
45  // x << 4 : 00a9,0000,0000,8765,0000,0000,4321,0000
46  // x | (x << 4) : 00a9,00a9,0000,8765,8765,0000,4321,4321
47  // 0x030C30C3 : 0000,0011,0000,1100,0011,0000,1100,0011
48  // x : 0000,00a9,0000,8700,0065,0000,4300,0021
49  x = (x | (x << 2)) & 0x09249249;
50  // x << 2 : 0000,a900,0087,0000,6500,0043,0000,2100
51  // x | (x << 2) : 0000,a9a9,0087,8700,6565,0043,4300,2121
52  // 0x09249249 : 0000,1001,0010,0100,1001,0010,0100,1001
53  // x : 0000,a009,0080,0700,6005,0040,0300,2001
54  return x;
55 #elif (AMREX_SPACEDIM == 2)
56  // x : 0000,0000,0000,0000,gfed,cba9,8765,4321
57  x = (x | (x << 8)) & 0x00FF00FF;
58  // x << 8 : 0000,0000,gfed,cba9,8765,4321,0000,0000
59  // x | (x << 8): 0000,0000,gfed,cba9,????,????,8765,4321
60  // 0x00FF00FF : 0000,0000,1111,1111,0000,0000,1111,1111
61  // x : 0000,0000,gfed,cba9,0000,0000,8765,4321
62  x = (x | (x << 4)) & 0x0F0F0F0F;
63  // x << 4 : 0000,gfed,cba9,0000,0000,8765,4321,0000
64  // x | (x << 4): 0000,gfed,????,cba9,0000,8765,????,4321
65  // 0x0F0F0F0F : 0000,1111,0000,1111,0000,1111,0000,1111
66  // x : 0000,gfed,0000,cba9,0000,8765,0000,4321
67  x = (x | (x << 2)) & 0x33333333;
68  // x << 2 : 00gf,ed00,00cb,a900,0087,6500,0043,2100
69  // x | (x << 2): 00gf,??ed,00cb,??a9,0087,??65,0043,??21
70  // 0x33333333 : 0011,0011,0011,0011,0011,0011,0011,0011
71  // x : 00gf,00ed,00cb,00a9,0087,0065,0043,0021
72  x = (x | (x << 1)) & 0x55555555;
73  // x << 1 : 0gf0,0ed0,0cb0,0a90,0870,0650,0430,0210
74  // x | (x << 1): 0g?f,0e?d,0c?b,0a?9,08?7,06?5,04?3,02?1
75  // 0x55555555 : 0101,0101,0101,0101,0101,0101,0101,0101
76  // x : 0g0f,0e0d,0c0b,0a09,0807,0605,0403,0201
77  return x;
78 #elif (AMREX_SPACEDIM == 1)
79  return x;
80 #endif
81 }
82 
97 std::uint32_t toUInt10 (amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept {
98  AMREX_ASSERT(x >= xmin && x < xmax);
99  constexpr std::uint32_t code_offset = (1U << 10);
100  return (std::uint32_t)(((x - xmin)/(xmax - xmin)) * code_offset);
101 }
102 
117 std::uint32_t toUInt16 (amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept {
118  AMREX_ASSERT(x >= xmin && x < xmax);
119  constexpr std::uint32_t code_offset = (1U << 16);
120  return (std::uint32_t)(((x - xmin)/(xmax - xmin)) * code_offset);
121 }
122 
135 std::uint32_t toUInt32 (amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept {
136  AMREX_ASSERT(x >= xmin && x < xmax);
137  constexpr unsigned long long code_offset = (1ULL << 32);
138  return (std::uint32_t)(((x - xmin)/(xmax - xmin)) * Real(code_offset));
139 }
140 
158 std::uint32_t get32BitCode (AMREX_D_DECL(Real x, Real y, Real z),
160  const GpuArray<amrex::Real,AMREX_SPACEDIM>& phi) noexcept {
161 #if (AMREX_SPACEDIM == 3)
162  std::uint32_t a = toUInt10(x, plo[0], phi[0]);
163  std::uint32_t b = toUInt10(y, plo[1], phi[1]);
164  std::uint32_t c = toUInt10(z, plo[2], phi[2]);
165 #elif (AMREX_SPACEDIM == 2)
166  std::uint32_t a = toUInt16(x, plo[0], phi[0]);
167  std::uint32_t b = toUInt16(y, plo[1], phi[1]);
168 #elif (AMREX_SPACEDIM == 1)
169  std::uint32_t a = toUInt32(x, plo[0], phi[0]);
170 #endif
171  return AMREX_D_TERM(makeSpace(a), | (makeSpace(b) << 1), | (makeSpace(c) << 2));
172 }
173 
185 #if (AMREX_SPACEDIM == 3)
187 std::uint32_t get32BitCode (const XDim3& p,
189  const GpuArray<amrex::Real,AMREX_SPACEDIM>& phi) noexcept {
190  return get32BitCode(p.x, p.y, p.z, plo, phi);
191 }
192 #endif
193 
194 }
195 #endif
#define AMREX_ASSERT(EX)
Definition: AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition: AMReX_Extension.H:119
#define AMREX_GPU_HOST_DEVICE
Definition: AMReX_GpuQualifiers.H:20
#define AMREX_D_TERM(a, b, c)
Definition: AMReX_SPACE.H:129
#define AMREX_D_DECL(a, b, c)
Definition: AMReX_SPACE.H:104
Definition: AMReX_Morton.H:12
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t toUInt32(amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept
Convert a Real to a uint32, keeping all significant bits. It is assumed that xmin <= x < xmax.
Definition: AMReX_Morton.H:135
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t toUInt16(amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept
Convert a Real to a uint32, keeping only 16 significant bits. This puts the first 16 bits of x into r...
Definition: AMReX_Morton.H:117
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t makeSpace(std::uint32_t x) noexcept
This makes space in the input 32-bit integer by splitting the bits so they can be interleaved.
Definition: AMReX_Morton.H:31
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t get32BitCode(AMREX_D_DECL(Real x, Real y, Real z), const GpuArray< amrex::Real, AMREX_SPACEDIM > &plo, const GpuArray< amrex::Real, AMREX_SPACEDIM > &phi) noexcept
Given a 3D real-space coordinate, returns a Morton code stored in an unsigned 32 bit integer.
Definition: AMReX_Morton.H:158
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::uint32_t toUInt10(amrex::Real x, amrex::Real xmin, amrex::Real xmax) noexcept
Convert a Real to a uint32, keeping only 10 significant bits. This puts the first 10 bits of x into r...
Definition: AMReX_Morton.H:97
Definition: AMReX_Array.H:34
Definition: AMReX_Dim3.H:13