@@ -33,6 +33,79 @@ namespace amrex {
33
33
34
34
using namespace ParticleIdCpus ;
35
35
36
+ namespace particle_impl {
37
+
38
+ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
39
+ Long unpack_id (const uint64_t idcpu) noexcept {
40
+ Long r = 0 ;
41
+
42
+ uint64_t sign = idcpu >> 63 ; // extract leftmost sign bit
43
+ uint64_t val = ((idcpu >> 24 ) & 0x7FFFFFFFFF ); // extract next 39 id bits
44
+
45
+ Long lval = static_cast <Long>(val); // bc we take -
46
+ r = (sign) ? lval : -lval;
47
+ return r;
48
+ }
49
+
50
+ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
51
+ int unpack_cpu (const uint64_t idcpu) noexcept {
52
+ return static_cast <int >(idcpu & 0x00FFFFFF );
53
+ }
54
+
55
+ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
56
+ void pack_id (uint64_t & idcpu, const Long id) noexcept {
57
+ // zero out the 40 leftmost bits, which store the sign and the abs of the id;
58
+ idcpu &= 0x00FFFFFF ;
59
+
60
+ uint64_t val;
61
+ uint64_t sign = id >= 0 ;
62
+ if (sign)
63
+ {
64
+ // 2**39-1, the max value representable in this fashion
65
+ AMREX_ASSERT (id <= 549755813887L );
66
+ val = id;
67
+ }
68
+ else
69
+ {
70
+ // -2**39-1, the min value representable in this fashion
71
+ AMREX_ASSERT (id >= -549755813887L );
72
+ val = -id;
73
+ }
74
+
75
+ (idcpu) |= (sign << 63 ); // put the sign in the leftmost bit
76
+ (idcpu) |= (val << 24 ); // put the val in the next 39
77
+ }
78
+
79
+ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
80
+ void pack_cpu (uint64_t & idcpu, const int cpu) noexcept {
81
+ // zero out the first 24 bits, which are used to store the cpu number
82
+ idcpu &= (~ 0x00FFFFFF );
83
+
84
+ AMREX_ASSERT (cpu >= 0 );
85
+ AMREX_ASSERT (cpu <= 16777215 ); // 2**24-1, the max representable number
86
+
87
+ idcpu |= cpu;
88
+ }
89
+
90
+ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
91
+ void make_invalid (uint64_t & idcpu) noexcept {
92
+ // RHS mask: 0111...
93
+ idcpu &= ~(uint64_t (1 ) << 63 );
94
+ }
95
+
96
+ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
97
+ void make_valid (uint64_t & idcpu) noexcept {
98
+ // RHS mask: 1000...
99
+ idcpu |= uint64_t (1 ) << 63 ;
100
+ }
101
+
102
+ [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
103
+ bool is_valid (const uint64_t idcpu) noexcept {
104
+ // the leftmost bit is our id's valid sign
105
+ return idcpu >> 63 ;
106
+ }
107
+ }
108
+
36
109
struct ParticleIDWrapper
37
110
{
38
111
uint64_t * m_idata;
@@ -64,40 +137,14 @@ struct ParticleIDWrapper
64
137
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
65
138
ParticleIDWrapper& operator = (const Long id) noexcept
66
139
{
67
- // zero out the 40 leftmost bits, which store the sign and the abs of the id;
68
- (*m_idata) &= 0x00FFFFFF ;
69
-
70
- uint64_t val;
71
- uint64_t sign = id >= 0 ;
72
- if (sign)
73
- {
74
- // 2**39-1, the max value representable in this fashion
75
- AMREX_ASSERT (id <= 549755813887L );
76
- val = id;
77
- }
78
- else
79
- {
80
- // -2**39-1, the min value representable in this fashion
81
- AMREX_ASSERT (id >= -549755813887L );
82
- val = -id;
83
- }
84
-
85
- (*m_idata) |= (sign << 63 ); // put the sign in the leftmost bit
86
- (*m_idata) |= (val << 24 ); // put the val in the next 39
140
+ particle_impl::pack_id (*m_idata, id);
87
141
return *this ;
88
142
}
89
143
90
144
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
91
145
operator Long () const noexcept
92
146
{
93
- Long r = 0 ;
94
-
95
- uint64_t sign = (*m_idata) >> 63 ; // extract leftmost sign bit
96
- uint64_t val = (((*m_idata) >> 24 ) & 0x7FFFFFFFFF ); // extract next 39 id bits
97
-
98
- Long lval = static_cast <Long>(val); // bc we take -
99
- r = (sign) ? lval : -lval;
100
- return r;
147
+ return particle_impl::unpack_id (*m_idata);
101
148
}
102
149
103
150
/* * Mark the particle as invalid
@@ -108,8 +155,7 @@ struct ParticleIDWrapper
108
155
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
109
156
void make_invalid () const noexcept
110
157
{
111
- // RHS mask: 0111...
112
- (*m_idata) &= ~(uint64_t (1 ) << 63 );
158
+ particle_impl::make_invalid (*m_idata);
113
159
}
114
160
115
161
/* * Mark the particle as valid
@@ -120,8 +166,7 @@ struct ParticleIDWrapper
120
166
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
121
167
void make_valid () const noexcept
122
168
{
123
- // RHS mask: 1000...
124
- (*m_idata) |= uint64_t (1 ) << 63 ;
169
+ particle_impl::make_valid (*m_idata);
125
170
}
126
171
127
172
/* * Check the particle is valid, via the sign of the id.
@@ -131,8 +176,7 @@ struct ParticleIDWrapper
131
176
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
132
177
bool is_valid () const noexcept
133
178
{
134
- // the leftmost bit is our id's valid sign
135
- return (*m_idata) >> 63 ;
179
+ return particle_impl::is_valid (*m_idata);
136
180
}
137
181
};
138
182
@@ -167,20 +211,14 @@ struct ParticleCPUWrapper
167
211
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
168
212
ParticleCPUWrapper& operator = (const int cpu) noexcept
169
213
{
170
- // zero out the first 24 bits, which are used to store the cpu number
171
- (*m_idata) &= (~ 0x00FFFFFF );
172
-
173
- AMREX_ASSERT (cpu >= 0 );
174
- AMREX_ASSERT (cpu <= 16777215 ); // 2**24-1, the max representable number
175
-
176
- (*m_idata) |= cpu;
214
+ particle_impl::pack_cpu (*m_idata, cpu);
177
215
return *this ;
178
216
}
179
217
180
218
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
181
219
operator int () const noexcept
182
220
{
183
- return static_cast < int >(( *m_idata) & 0x00FFFFFF );
221
+ return particle_impl::unpack_cpu ( *m_idata);
184
222
}
185
223
};
186
224
@@ -196,14 +234,7 @@ struct ConstParticleIDWrapper
196
234
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
197
235
operator Long () const noexcept
198
236
{
199
- Long r = 0 ;
200
-
201
- uint64_t sign = (*m_idata) >> 63 ; // extract leftmost sign bit
202
- uint64_t val = (((*m_idata) >> 24 ) & 0x7FFFFFFFFF ); // extract next 39 id bits
203
-
204
- Long lval = static_cast <Long>(val); // bc we take -
205
- r = (sign) ? lval : -lval;
206
- return r;
237
+ return particle_impl::unpack_id (*m_idata);
207
238
}
208
239
209
240
/* * Check the sign of the id.
@@ -213,8 +244,7 @@ struct ConstParticleIDWrapper
213
244
[[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
214
245
bool is_valid () const noexcept
215
246
{
216
- // the leftmost bit is our id's valid sign
217
- return (*m_idata) >> 63 ;
247
+ return particle_impl::is_valid (*m_idata);
218
248
}
219
249
};
220
250
@@ -228,7 +258,9 @@ struct ConstParticleCPUWrapper
228
258
{}
229
259
230
260
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
231
- operator int () const noexcept { return static_cast <int >((*m_idata) & 0x00FFFFFF ); }
261
+ operator int () const noexcept {
262
+ return particle_impl::unpack_cpu (*m_idata);
263
+ }
232
264
};
233
265
234
266
/* * Set the idcpu value at once, based on a particle id and cpuid
0 commit comments