Skip to content

Commit 76eaae4

Browse files
Add wrappers to invalidate particles and set id/cpu from Python (#435)
To see how this is used, see [tests/test_particleTile.py](https://github.com/AMReX-Codes/pyamrex/pull/435/files#diff-ecc0338faa7592dbb084e945148b2aaa8f982e06dbc8cdcf72dcdf751a02dacb) --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 1e212aa commit 76eaae4

File tree

3 files changed

+121
-14
lines changed

3 files changed

+121
-14
lines changed

cmake/dependencies/AMReX.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ option(pyAMReX_amrex_internal "Download & build AMReX" ON)
8686
set(pyAMReX_amrex_repo "https://github.com/AMReX-Codes/amrex.git"
8787
CACHE STRING
8888
"Repository URI to pull and build AMReX from if(pyAMReX_amrex_internal)")
89-
set(pyAMReX_amrex_branch "25.04"
89+
set(pyAMReX_amrex_branch "793ea9f717590d66d178a86298b82aac244b77a7"
9090
CACHE STRING
9191
"Repository branch for pyAMReX_amrex_repo if(pyAMReX_amrex_internal)")
9292

src/Particle/ParticleContainer.cpp

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* Copyright 2022 The AMReX Community
22
*
3-
* Authors: Ryan Sandberg, Axel Huebl
3+
* Authors: Ryan Sandberg, Axel Huebl, Andrew Myers
44
* License: BSD-3-Clause-LBNL
55
*/
66
#include "ParticleContainer.H"
@@ -14,21 +14,70 @@ namespace
1414
{
1515
using namespace amrex;
1616

17-
// Note - this function MUST be consistent with AMReX_Particle.H
18-
Long unpack_id (uint64_t idcpu) {
19-
Long r = 0;
17+
py::object pack_ids (py::array_t<uint64_t> idcpus,
18+
py::array_t<amrex::Long> ids)
19+
{
20+
if (idcpus.ndim() != 1) {
21+
throw std::runtime_error("Input should be 1-D NumPy array");
22+
}
23+
24+
auto buf = idcpus.request();
25+
auto buf2 = ids.request();
26+
if (buf.size != buf2.size) {
27+
throw std::runtime_error("sizes do not match!");
28+
}
29+
30+
int N = idcpus.shape()[0];
31+
for (int i = 0; i < N; i++) {
32+
uint64_t* idcpus_ptr = (uint64_t*) buf.ptr;
33+
amrex::Long* ids_ptr = (amrex::Long*) buf2.ptr;
34+
particle_impl::pack_id(idcpus_ptr[i], ids_ptr[i]);
35+
}
36+
return py::cast<py::none>(Py_None);
37+
}
2038

21-
uint64_t sign = idcpu >> 63; // extract leftmost sign bit
22-
uint64_t val = ((idcpu >> 24) & 0x7FFFFFFFFF); // extract next 39 id bits
39+
py::object pack_cpus (py::array_t<uint64_t> idcpus,
40+
py::array_t<int> cpus)
41+
{
42+
if (idcpus.ndim() != 1) {
43+
throw std::runtime_error("Input should be 1-D NumPy array");
44+
}
45+
46+
auto buf = idcpus.request();
47+
auto buf2 = cpus.request();
48+
if (buf.size != buf2.size) {
49+
throw std::runtime_error("sizes do not match!");
50+
}
51+
52+
int N = idcpus.shape()[0];
53+
for (int i = 0; i < N; i++) {
54+
uint64_t* idcpus_ptr = (uint64_t*) buf.ptr;
55+
int* cpus_ptr = (int*) buf2.ptr;
56+
particle_impl::pack_cpu(idcpus_ptr[i], cpus_ptr[i]);
57+
}
58+
return py::cast<py::none>(Py_None);
59+
}
2360

24-
Long lval = static_cast<Long>(val); // bc we take -
25-
r = (sign) ? lval : -lval;
26-
return r;
61+
Long unpack_id (uint64_t idcpu) {
62+
return particle_impl::unpack_id(idcpu);
2763
}
2864

29-
// Note - this function MUST be consistent with AMReX_Particle.H
3065
int unpack_cpu (uint64_t idcpu) {
31-
return static_cast<int>(idcpu & 0x00FFFFFF);
66+
return particle_impl::unpack_cpu(idcpu);
67+
}
68+
69+
uint64_t make_invalid (uint64_t idcpu) {
70+
particle_impl::make_invalid(idcpu);
71+
return idcpu;
72+
}
73+
74+
uint64_t make_valid (uint64_t idcpu) {
75+
particle_impl::make_valid(idcpu);
76+
return idcpu;
77+
}
78+
79+
bool is_valid (const uint64_t idcpu) {
80+
return particle_impl::is_valid(idcpu);
3281
}
3382
}
3483

@@ -61,6 +110,11 @@ void init_ParticleContainer(py::module& m) {
61110
init_ParticleContainer_WarpX(m);
62111

63112
// for particle idcpu arrays
113+
m.def("pack_ids", &pack_ids);
114+
m.def("pack_cpus", &pack_cpus);
64115
m.def("unpack_ids", py::vectorize(unpack_id));
65116
m.def("unpack_cpus", py::vectorize(unpack_cpu));
117+
m.def("make_invalid", make_invalid);
118+
m.def("make_valid", make_valid);
119+
m.def("is_valid", is_valid);
66120
}

tests/test_particleTile.py

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,61 @@ def test_ptile_aos_3d():
156156

157157

158158
def test_ptile_aos():
159-
idcpu = np.array([100, 100, 100, 100, 100], dtype=np.uint64)
159+
idcpu = np.array(
160+
[
161+
9223372036871553124,
162+
9223372036871553124,
163+
9223372036871553124,
164+
9223372036871553124,
165+
9223372036871553124,
166+
],
167+
dtype=np.uint64,
168+
)
169+
ids = amr.unpack_ids(idcpu)
170+
cpus = amr.unpack_cpus(idcpu)
171+
assert np.array_equal(ids, np.array([1, 1, 1, 1, 1]))
172+
assert np.array_equal(cpus, np.array([100, 100, 100, 100, 100]))
173+
174+
assert amr.is_valid(idcpu[0])
175+
idcpu[0] = amr.make_invalid(idcpu[0])
176+
assert not amr.is_valid(idcpu[0])
177+
idcpu[0] = amr.make_valid(idcpu[0])
178+
assert amr.is_valid(idcpu[0])
179+
180+
# the leftmost bit stores the sign of the id
181+
# the next 39 store its absolute value
182+
# the rightmost 24 then store the cpu number
183+
# using this scheme, id = 1 cpu = 100
184+
# corresponds to 9223372036871553124
185+
assert idcpu[0] == 9223372036871553124
186+
187+
idcpu = np.array([0, 0, 0, 0, 0], dtype=np.uint64)
188+
amr.pack_ids(idcpu, np.array([1, 1, 1, 1, 1], dtype=np.int64))
189+
amr.pack_cpus(idcpu, np.array([100, 100, 100, 100, 100], dtype=np.int32))
190+
print(idcpu)
191+
assert np.array_equal(
192+
idcpu,
193+
np.array(
194+
[
195+
9223372036871553124,
196+
9223372036871553124,
197+
9223372036871553124,
198+
9223372036871553124,
199+
9223372036871553124,
200+
]
201+
),
202+
)
203+
204+
idcpu = np.array(
205+
[
206+
9223372036871553124,
207+
9223372036871553124,
208+
9223372036871553124,
209+
9223372036871553124,
210+
9223372036871553124,
211+
]
212+
)
160213
ids = amr.unpack_ids(idcpu)
161214
cpus = amr.unpack_cpus(idcpu)
162-
assert np.array_equal(ids, np.array([0, 0, 0, 0, 0]))
215+
assert np.array_equal(ids, np.array([1, 1, 1, 1, 1]))
163216
assert np.array_equal(cpus, np.array([100, 100, 100, 100, 100]))

0 commit comments

Comments
 (0)