Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
bmi.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
24
25namespace shamrock::sfc::bmi {
26
27 template<class inttype, int interleaving>
28 inttype expand_bits(inttype);
29
30 // 21bit number and 2 interleaving bits (for 64bits)
31 template<>
32 inline u64 expand_bits<u64, 2>(u64 x) {
33 x &= 0x1fffffUll;
34 x = (x | x << 32Ull) & 0x1f00000000ffffUll;
35 x = (x | x << 16Ull) & 0x1f0000ff0000ffUll;
36 x = (x | x << 8Ull) & 0x100f00f00f00f00fUll;
37 x = (x | x << 4Ull) & 0x10c30c30c30c30c3Ull;
38 x = (x | x << 2Ull) & 0x1249249249249249Ull;
39 return x;
40 }
41
42 // 10bit number and 2 interleaving bits (for 32 bits)
43 template<>
44 inline u32 expand_bits<u32, 2>(u32 x) {
45 x &= 0x3ffU;
46 x = (x | x << 16U) & 0x30000ffU;
47 x = (x | x << 8U) & 0x300f00fU;
48 x = (x | x << 4U) & 0x30c30c3U;
49 x = (x | x << 2U) & 0x9249249U;
50 return x;
51 }
52
53 // 16 bit number 1 interleaving bit (for 32bits)
54 template<>
55 inline u32 expand_bits<u32, 1>(u32 x) {
56 x = (x | (x << 8U)) & 0x00FF00FFU;
57 x = (x | (x << 4U)) & 0x0F0F0F0FU;
58 x = (x | (x << 2U)) & 0x33333333U;
59 x = (x | (x << 1U)) & 0x55555555U;
60 return x;
61 }
62
63 // 32 bit number 1 interleaving bit (for 64bits)
64 template<>
65 inline u64 expand_bits<u64, 1>(u64 x) {
66 x = (x | (x << 16Ull)) & 0x0000FFFF0000FFFFull;
67 x = (x | (x << 8Ull)) & 0x00FF00FF00FF00FFull;
68 x = (x | (x << 4Ull)) & 0x0F0F0F0F0F0F0F0Full;
69 x = (x | (x << 2Ull)) & 0x3333333333333333ull;
70 x = (x | (x << 1Ull)) & 0x5555555555555555ull;
71 return x;
72 }
73
74 template<>
75 inline u32 expand_bits<u32, 0>(u32 x) {
76 return x;
77 }
78
79 template<>
80 inline u64 expand_bits<u64, 0>(u64 x) {
81 return x;
82 }
83
84 template<class inttype, int interleaving>
85 inttype contract_bits(inttype);
86
87 template<>
88 inline u64 contract_bits<u64, 2>(u64 src) {
89 // src = src & 0x9249249249249249;
90 src = (src | (src >> 2Ull)) & 0x30c30c30c30c30c3Ull;
91 src = (src | (src >> 4Ull)) & 0xf00f00f00f00f00fUll;
92 src = (src | (src >> 8Ull)) & 0x00ff0000ff0000ffUll;
93 src = (src | (src >> 16Ull)) & 0xffff00000000ffffUll;
94 src = (src | (src >> 32Ull)) & 0x00000000ffffffffUll;
95 return src;
96 }
97
98 template<>
99 inline u64 contract_bits<u64, 1>(u64 src) {
100 src = (src | (src >> 1Ull)) & 0x3333333333333333Ull;
101 src = (src | (src >> 2Ull)) & 0x0f0f0f0f0f0f0f0fUll;
102 src = (src | (src >> 4Ull)) & 0x00ff00ff00ff00ffUll;
103 src = (src | (src >> 8Ull)) & 0x0000ffff0000ffffUll;
104 src = (src | (src >> 16Ull)) & 0x00000000ffffffffUll;
105 return src;
106 }
107
108 template<>
109 inline u64 contract_bits<u64, 0>(u64 src) {
110 return src;
111 }
112
113 template<>
114 inline u32 contract_bits<u32, 2>(u32 src) {
115 src = (src | src >> 2U) & 0x30C30C3U;
116 src = (src | src >> 4U) & 0xF00F00FU;
117 src = (src | src >> 8U) & 0xFF0000FFU;
118 src = (src | src >> 16U) & 0xFFFFU;
119 return src;
120 }
121
122 template<>
123 inline u32 contract_bits<u32, 1>(u32 src) {
124 src = (src | (src >> 1U)) & 0x33333333U;
125 src = (src | (src >> 2U)) & 0x0f0f0f0fU;
126 src = (src | (src >> 4U)) & 0x00ff00ffU;
127 src = (src | (src >> 8U)) & 0x0000ffffU;
128 return src;
129 }
130
131 template<>
132 inline u32 contract_bits<u32, 0>(u32 src) {
133 return src;
134 }
135
136} // namespace shamrock::sfc::bmi
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer