IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
Archive.hpp
1//
2// Class Archive
3// Class to (de-)serialize in MPI communication.
4//
5#include "Archive.h"
6
7namespace ippl {
8 namespace detail {
9 KOKKOS_INLINE_FUNCTION void copyBytes(char* dst, const char* src, size_t size) {
10 for (size_t i = 0; i < size; ++i) {
11 dst[i] = src[i];
12 }
13 }
14
15 template <class... Properties>
16 Archive<Properties...>::Archive(size_type size)
17 : writepos_m(0)
18 , readpos_m(0)
19 , buffer_m("buffer", size) {}
20
21 // -----------------------------------
22 // Scalar serialize
23 template <class... Properties>
24 template <typename T, class... ViewArgs>
25 void Archive<Properties...>::serialize(const Kokkos::View<T*, ViewArgs...>& view,
26 size_type nsends) {
27 constexpr size_t size = sizeof(T);
28 char* dst_ptr = (char*)(buffer_m.data()) + writepos_m;
29 char* src_ptr = (char*)(view.data());
30 assert(writepos_m + (nsends * size) <= buffer_m.size());
31 // construct temp views of the src/dst buffers of the correct size (bytes)
32 using src_view_type =
33 Kokkos::View<char*, typename Kokkos::View<T*, ViewArgs...>::memory_space,
34 Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
35 using dst_view_type =
36 Kokkos::View<char*, typename buffer_type::memory_space,
37 Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
38 src_view_type src_view(src_ptr, size * nsends);
39 dst_view_type dst_view(dst_ptr, size * nsends);
40 Kokkos::deep_copy(dst_view, src_view);
41 Kokkos::fence();
42 writepos_m += (nsends * size);
43 }
44
45 // -----------------------------------
46 // Vector serialize
47 template <class... Properties>
48 template <typename T, unsigned Dim, class... ViewArgs>
50 const Kokkos::View<Vector<T, Dim>*, ViewArgs...>& view, size_type nsends) {
51 constexpr size_t size = sizeof(T);
52 char* dst_ptr = (char*)(buffer_m.data());
53 ippl::Vector<T, Dim>* src_ptr = view.data();
54 auto wp = writepos_m;
55 // The Kokkos range policies expect int64
56 // so we have to explicitly specify size_type (uint64)
57 using exec_space = typename Kokkos::View<T*, ViewArgs...>::execution_space;
58 using mdrange_t =
59 Kokkos::MDRangePolicy<Kokkos::Rank<2>, Kokkos::IndexType<size_type>, exec_space>;
60 Kokkos::parallel_for(
61 "Archive::serialize()", mdrange_t({0, 0}, {(long int)nsends, Dim}),
62 KOKKOS_LAMBDA(const size_type i, const size_t d) {
63 const char* src = reinterpret_cast<const char*>(&src_ptr[i][d]);
64 char* dst = dst_ptr + (Dim * i + d) * size + wp;
65 copyBytes(dst, src, size);
66 });
67
68 Kokkos::fence();
69 writepos_m += Dim * size * nsends;
70 }
71
72 // -----------------------------------
73 // Scalar Deserialize
74 template <class... Properties>
75 template <typename T, class... ViewArgs>
76 void Archive<Properties...>::deserialize(Kokkos::View<T*, ViewArgs...>& view,
77 size_type nrecvs) {
78 // if we have to enlarge the destination view
79 if (nrecvs > view.extent(0)) {
80 Kokkos::realloc(view, nrecvs);
81 }
82 //
83 constexpr size_t size = sizeof(T);
84 char* src_ptr = (char*)(buffer_m.data()) + readpos_m;
85 char* dst_ptr = (char*)(view.data());
86 assert(readpos_m + (nrecvs * size) <= buffer_m.size());
87 // construct temp views of the src/dst buffers of the correct size (bytes)
88 using src_view_type =
89 Kokkos::View<char*, typename buffer_type::memory_space,
90 Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
91 using dst_view_type =
92 Kokkos::View<char*, typename Kokkos::View<T*, ViewArgs...>::memory_space,
93 Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
94 src_view_type src_view(src_ptr, size * nrecvs);
95 dst_view_type dst_view(dst_ptr, size * nrecvs);
96 Kokkos::deep_copy(dst_view, src_view);
97 Kokkos::fence();
98 readpos_m += (nrecvs * size);
99 }
100
101 // -----------------------------------
102 // Vector Deserialize
103 template <class... Properties>
104 template <typename T, unsigned Dim, class... ViewArgs>
105 void Archive<Properties...>::deserialize(Kokkos::View<Vector<T, Dim>*, ViewArgs...>& view,
106 size_type nrecvs)
107 {
108 // if we have to enlarge the destination view
109 if (nrecvs > view.extent(0)) {
110 Kokkos::realloc(view, nrecvs);
111 }
112 //
113 constexpr size_t size = sizeof(T);
114 char* src_ptr = (char*)(buffer_m.data());
115 ippl::Vector<T, Dim>* dst_ptr = view.data();
116 auto rp = readpos_m;
117 using exec_space = typename Kokkos::View<T*, ViewArgs...>::execution_space;
118 using mdrange_t =
119 Kokkos::MDRangePolicy<Kokkos::Rank<2>, Kokkos::IndexType<size_type>, exec_space>;
120 Kokkos::parallel_for(
121 "Archive::deserialize()", mdrange_t({0, 0}, {(long int)nrecvs, Dim}),
122 KOKKOS_LAMBDA(const size_type i, const size_t d) {
123 const char* src = src_ptr + (Dim * i + d) * size + rp;
124 char* dst = reinterpret_cast<char*>(&dst_ptr[i][d]);
125 copyBytes(dst, src, size);
126 });
127 Kokkos::fence();
128 readpos_m += Dim * size * nrecvs;
129 }
130 } // namespace detail
131} // namespace ippl
Definition Vector.h:23
Definition Archive.h:29
Definition Archive.h:20