Branch data Line data Source code
1 : : //
2 : : // Class Archive
3 : : // Class to (de-)serialize in MPI communication.
4 : : //
5 : : #include <cstring>
6 : :
7 : : #include "Archive.h"
8 : :
9 : : namespace ippl {
10 : : namespace detail {
11 : :
12 : : template <class... Properties>
13 : 26 : Archive<Properties...>::Archive(size_type size)
14 : 26 : : writepos_m(0)
15 : 26 : , readpos_m(0)
16 : 26 : , buffer_m("buffer", size) {}
17 : :
18 : : template <class... Properties>
19 : : template <typename T, class... ViewArgs>
20 : 0 : void Archive<Properties...>::serialize(const Kokkos::View<T*, ViewArgs...>& view,
21 : : size_type nsends) {
22 : : using exec_space = typename Kokkos::View<T*, ViewArgs...>::execution_space;
23 : : using policy_type = Kokkos::RangePolicy<exec_space>;
24 : :
25 : 0 : size_t size = sizeof(T);
26 [ # # # # ]: 0 : Kokkos::parallel_for(
27 : 0 : "Archive::serialize()", policy_type(0, nsends),
28 [ # # # # : 0 : KOKKOS_CLASS_LAMBDA(const size_type i) {
# # # # ]
29 : 0 : std::memcpy(buffer_m.data() + i * size + writepos_m, view.data() + i, size);
30 : : });
31 [ # # # # ]: 0 : Kokkos::fence();
32 : 0 : writepos_m += size * nsends;
33 : 0 : }
34 : :
35 : : template <class... Properties>
36 : : template <typename T, unsigned Dim, class... ViewArgs>
37 : 0 : void Archive<Properties...>::serialize(
38 : : const Kokkos::View<Vector<T, Dim>*, ViewArgs...>& view, size_type nsends) {
39 : : using exec_space = typename Kokkos::View<T*, ViewArgs...>::execution_space;
40 : :
41 : 0 : size_t size = sizeof(T);
42 : : // Default index type for range policies is int64,
43 : : // so we have to explicitly specify size_type (uint64)
44 : : using mdrange_t =
45 : : Kokkos::MDRangePolicy<Kokkos::Rank<2>, Kokkos::IndexType<size_type>, exec_space>;
46 [ # # # # ]: 0 : Kokkos::parallel_for(
47 : : "Archive::serialize()",
48 : : // The constructor for Kokkos range policies always
49 : : // expects int64 regardless of index type provided
50 : : // by template parameters, so the typecast is necessary
51 : : // to avoid compiler warnings
52 : 0 : mdrange_t({0, 0}, {(long int)nsends, Dim}),
53 [ # # # # : 0 : KOKKOS_CLASS_LAMBDA(const size_type i, const size_t d) {
# # # # ]
54 : 0 : std::memcpy(buffer_m.data() + (Dim * i + d) * size + writepos_m,
55 : 0 : &(*(view.data() + i))[d], size);
56 : : });
57 [ # # # # ]: 0 : Kokkos::fence();
58 : 0 : writepos_m += Dim * size * nsends;
59 : 0 : }
60 : :
61 : : template <class... Properties>
62 : : template <typename T, class... ViewArgs>
63 : 0 : void Archive<Properties...>::deserialize(Kokkos::View<T*, ViewArgs...>& view,
64 : : size_type nrecvs) {
65 : : using exec_space = typename Kokkos::View<T*, ViewArgs...>::execution_space;
66 : : using policy_type = Kokkos::RangePolicy<exec_space>;
67 : :
68 : 0 : size_t size = sizeof(T);
69 [ # # ]: 0 : if (nrecvs > view.extent(0)) {
70 : 0 : Kokkos::realloc(view, nrecvs);
71 : : }
72 [ # # # # ]: 0 : Kokkos::parallel_for(
73 : 0 : "Archive::deserialize()", policy_type(0, nrecvs),
74 [ # # # # : 0 : KOKKOS_CLASS_LAMBDA(const size_type i) {
# # # # #
# ]
75 : 0 : std::memcpy(view.data() + i, buffer_m.data() + i * size + readpos_m, size);
76 : : });
77 : : // Wait for deserialization kernel to complete
78 : : // (as with serialization kernels)
79 [ # # # # ]: 0 : Kokkos::fence();
80 : 0 : readpos_m += size * nrecvs;
81 : 0 : }
82 : :
83 : : template <class... Properties>
84 : : template <typename T, unsigned Dim, class... ViewArgs>
85 : 0 : void Archive<Properties...>::deserialize(Kokkos::View<Vector<T, Dim>*, ViewArgs...>& view,
86 : : size_type nrecvs) {
87 : : using exec_space = typename Kokkos::View<T*, ViewArgs...>::execution_space;
88 : :
89 : 0 : size_t size = sizeof(T);
90 [ # # ]: 0 : if (nrecvs > view.extent(0)) {
91 : 0 : Kokkos::realloc(view, nrecvs);
92 : : }
93 : : using mdrange_t =
94 : : Kokkos::MDRangePolicy<Kokkos::Rank<2>, Kokkos::IndexType<size_type>, exec_space>;
95 [ # # # # ]: 0 : Kokkos::parallel_for(
96 : 0 : "Archive::deserialize()", mdrange_t({0, 0}, {(long int)nrecvs, Dim}),
97 [ # # # # : 0 : KOKKOS_CLASS_LAMBDA(const size_type i, const size_t d) {
# # # # #
# ]
98 : 0 : std::memcpy(&(*(view.data() + i))[d],
99 : 0 : buffer_m.data() + (Dim * i + d) * size + readpos_m, size);
100 : : });
101 [ # # # # ]: 0 : Kokkos::fence();
102 : 0 : readpos_m += Dim * size * nrecvs;
103 : 0 : }
104 : : } // namespace detail
105 : : } // namespace ippl
|