5 std::vector< Kokkos::View<size_t*> > sendIdxs,
6 std::vector< Kokkos::View<size_t*> > recvIdxs) :
7 data_m(
"FEMVector::data", n), boundaryInfo_m(new BoundaryInfo(std::move(neighbors),
8 std::move(sendIdxs), std::move(recvIdxs))) {
23 boundaryInfo_m(other.boundaryInfo_m) {
30 std::vector< Kokkos::View<size_t*> > sendIdxs,
31 std::vector< Kokkos::View<size_t*> > recvIdxs) :
32 neighbors_m(neighbors), sendIdxs_m(sendIdxs), recvIdxs_m(recvIdxs) {
40 if (!boundaryInfo_m) {
42 "FEMVector::fillHalo()",
43 "Cannot do halo operations, as no MPI communication information is provided. "
44 "Did you use the correct constructor to construct the FEMVector?");
47 using memory_space =
typename Kokkos::View<size_t*>::memory_space;
49 std::vector<MPI_Request> requests(boundaryInfo_m->neighbors_m.size());
52 for (
size_t i = 0; i < boundaryInfo_m->neighbors_m.size(); ++i) {
53 size_t neighborRank = boundaryInfo_m->neighbors_m[i];
54 size_t nsends = boundaryInfo_m->sendIdxs_m[i].extent(0);
55 size_t tag = mpi::tag::FEMVECTOR + ippl::Comm->rank();
58 pack(boundaryInfo_m->sendIdxs_m[i]);
62 mpi::Communicator::buffer_type<memory_space> archive =
63 ippl::Comm->getBuffer<memory_space, T>(nsends);
64 ippl::Comm->isend(neighborRank, tag, boundaryInfo_m->commBuffer_m, *archive,
66 archive->resetWritePos();
70 for (
size_t i = 0; i < boundaryInfo_m->neighbors_m.size(); ++i) {
71 size_t neighborRank = boundaryInfo_m->neighbors_m[i];
72 size_t nrecvs = boundaryInfo_m->recvIdxs_m[i].extent(0);
73 size_t tag = mpi::tag::FEMVECTOR + boundaryInfo_m->neighbors_m[i];
77 mpi::Communicator::buffer_type<memory_space> archive =
78 ippl::Comm->getBuffer<memory_space, T>(nrecvs);
79 ippl::Comm->recv(neighborRank, tag, boundaryInfo_m->commBuffer_m, *archive,
80 nrecvs *
sizeof(T), nrecvs);
81 archive->resetReadPos();
84 unpack<Assign>(boundaryInfo_m->recvIdxs_m[i]);
87 if (requests.size() > 0) {
88 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
90 ippl::Comm->freeAllBuffers();
97 if (!boundaryInfo_m) {
99 "FEMVector::accumulateHalo()",
100 "Cannot do halo operations, as no MPI communication information is provided. "
101 "Did you use the correct constructor to construct the FEMVector?");
104 using memory_space =
typename Kokkos::View<size_t*>::memory_space;
106 std::vector<MPI_Request> requests(boundaryInfo_m->neighbors_m.size());
109 for (
size_t i = 0; i < boundaryInfo_m->neighbors_m.size(); ++i) {
110 size_t neighborRank = boundaryInfo_m->neighbors_m[i];
111 size_t nsends = boundaryInfo_m->recvIdxs_m[i].extent(0);
112 size_t tag = mpi::tag::FEMVECTOR + ippl::Comm->rank();
115 pack(boundaryInfo_m->recvIdxs_m[i]);
119 mpi::Communicator::buffer_type<memory_space> archive =
120 ippl::Comm->getBuffer<memory_space, T>(nsends);
121 ippl::Comm->isend(neighborRank, tag, boundaryInfo_m->commBuffer_m, *archive,
122 requests[i], nsends);
123 archive->resetWritePos();
127 for (
size_t i = 0; i < boundaryInfo_m->neighbors_m.size(); ++i) {
128 size_t neighborRank = boundaryInfo_m->neighbors_m[i];
129 size_t nrecvs = boundaryInfo_m->sendIdxs_m[i].extent(0);
130 size_t tag = mpi::tag::FEMVECTOR + boundaryInfo_m->neighbors_m[i];
134 mpi::Communicator::buffer_type<memory_space> archive =
135 ippl::Comm->getBuffer<memory_space, T>(nrecvs);
136 ippl::Comm->recv(neighborRank, tag, boundaryInfo_m->commBuffer_m, *archive,
137 nrecvs *
sizeof(T), nrecvs);
138 archive->resetReadPos();
141 unpack<AssignAdd>(boundaryInfo_m->sendIdxs_m[i]);
144 if (requests.size() > 0) {
145 MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE);
147 ippl::Comm->freeAllBuffers();
151 template <
typename T>
154 if (!boundaryInfo_m) {
157 "FEMVector::setHalo()",
158 "Cannot do halo operations, as no MPI communication information is provided. "
159 "Did you use the correct constructor to construct the FEMVector?");
162 for (
size_t i = 0; i < boundaryInfo_m->neighbors_m.size(); ++i) {
163 auto& view = boundaryInfo_m->recvIdxs_m[i];
164 Kokkos::parallel_for(
"FEMVector::setHalo()",view.extent(0),
165 KOKKOS_CLASS_LAMBDA(
const size_t& j){
166 data_m[view(j)] = setValue;
173 template <
typename T>
175 Kokkos::parallel_for(
"FEMVector::operator=(T value)", data_m.extent(0),
176 KOKKOS_CLASS_LAMBDA(
const size_t& i){
184 template <
typename T>
185 template <
typename E,
size_t N>
188 capture_type expr_ =
reinterpret_cast<const capture_type&
>(expr);
189 Kokkos::parallel_for(
"FEMVector::operator=(Expression)", data_m.extent(0),
190 KOKKOS_CLASS_LAMBDA(
const size_t& i){
191 data_m[i] = expr_(i);
198 template <
typename T>
201 Kokkos::parallel_for(
"FEMVector::operator=(FEMVector)", data_m.extent(0),
202 KOKKOS_CLASS_LAMBDA(
const size_t& i){
210 template <
typename T>
216 template <
typename T>
218 return this->operator[](i);
222 template <
typename T>
228 template <
typename T>
230 return data_m.extent(0);
233 template <
typename T>
236 if (boundaryInfo_m) {
239 std::vector< Kokkos::View<size_t*> > newSendIdxs;
240 std::vector< Kokkos::View<size_t*> > newRecvIdxs;
242 for (
size_t i = 0; i < boundaryInfo_m->neighbors_m.size(); ++i) {
243 newSendIdxs.emplace_back(Kokkos::View<size_t*>(boundaryInfo_m->sendIdxs_m[i].label(),
244 boundaryInfo_m->sendIdxs_m[i].extent(0)));
245 Kokkos::deep_copy(newSendIdxs[i], boundaryInfo_m->sendIdxs_m[i]);
247 newRecvIdxs.emplace_back(Kokkos::View<size_t*>(boundaryInfo_m->recvIdxs_m[i].label(),
248 boundaryInfo_m->recvIdxs_m[i].extent(0)));
250 Kokkos::deep_copy(newRecvIdxs[i], boundaryInfo_m->recvIdxs_m[i]);
254 FEMVector<T> newVector(size(), boundaryInfo_m->neighbors_m, newSendIdxs, newRecvIdxs);
268 template <
typename T>
269 template <
typename K>
272 if (boundaryInfo_m) {
275 std::vector< Kokkos::View<size_t*> > newSendIdxs;
276 std::vector< Kokkos::View<size_t*> > newRecvIdxs;
278 for (
size_t i = 0; i < boundaryInfo_m->neighbors_m.size(); ++i) {
279 newSendIdxs.emplace_back(Kokkos::View<size_t*>(boundaryInfo_m->sendIdxs_m[i].label(),
280 boundaryInfo_m->sendIdxs_m[i].extent(0)));
281 Kokkos::deep_copy(newSendIdxs[i], boundaryInfo_m->sendIdxs_m[i]);
283 newRecvIdxs.emplace_back(Kokkos::View<size_t*>(boundaryInfo_m->recvIdxs_m[i].label(),
284 boundaryInfo_m->recvIdxs_m[i].extent(0)));
286 Kokkos::deep_copy(newRecvIdxs[i], boundaryInfo_m->recvIdxs_m[i]);
290 FEMVector<K> newVector(size(), boundaryInfo_m->neighbors_m, newSendIdxs, newRecvIdxs);
301 template <
typename T>
304 if (!boundaryInfo_m) {
307 "Cannot do halo operations, as no MPI communication information is provided. "
308 "Did you use the correct constructor to construct the FEMVector?");
311 size_t nIdxs = idxStore.extent(0);
312 auto& bufferData = boundaryInfo_m->commBuffer_m.buffer;
314 if (bufferData.size() < nIdxs) {
315 int overalloc = Comm->getDefaultOverallocation();
316 Kokkos::realloc(bufferData, nIdxs * overalloc);
319 Kokkos::parallel_for(
"FEMVector::pack()", nIdxs,
320 KOKKOS_CLASS_LAMBDA(
const size_t& i) {
321 bufferData(i) = data_m(idxStore(i));
328 template <
typename T>
329 template <
typename Op>
332 if (!boundaryInfo_m) {
334 "FEMVector::unpack()",
335 "Cannot do halo operations, as no MPI communication information is provided. "
336 "Did you use the correct constructor to construct the FEMVector?");
339 size_t nIdxs = idxStore.extent(0);
340 auto& bufferData = boundaryInfo_m->commBuffer_m.buffer;
341 if (bufferData.size() < nIdxs) {
342 int overalloc = Comm->getDefaultOverallocation();
343 Kokkos::realloc(bufferData, nIdxs * overalloc);
347 Kokkos::parallel_for(
"FEMVector::unpack()", nIdxs,
348 KOKKOS_CLASS_LAMBDA(
const size_t& i) {
349 op(data_m(idxStore(i)), bufferData(i));
Definition IpplException.h:6
1D vector used in the context of FEM.
Definition FEMVector.h:34
void unpack(const Kokkos::View< size_t * > &idxStore)
Unpack data from BoundaryInfo::commBuffer_m into FEMVector::data_m after communication.
Definition FEMVector.hpp:330
void fillHalo()
Copy values from neighboring ranks into local halo.
Definition FEMVector.hpp:38
FEMVector< K > skeletonCopy() const
Create a new FEMVector with different data type, but same size and boundary infromation.
Definition FEMVector.hpp:270
FEMVector< T > & operator=(T value)
Set all the values of the vector to value.
Definition FEMVector.hpp:174
const Kokkos::View< T * > & getView() const
Get underlying data view.
Definition FEMVector.hpp:223
KOKKOS_INLINE_FUNCTION T operator()(size_t i) const
Subscript operator to get value at position i.
Definition FEMVector.hpp:217
void pack(const Kokkos::View< size_t * > &idxStore)
Pack data into BoundaryInfo::commBuffer_m for MPI communication.
Definition FEMVector.hpp:302
void accumulateHalo()
Accumulate halo values in neighbor.
Definition FEMVector.hpp:95
size_t size() const
Get the size (number of elements) of the vector.
Definition FEMVector.hpp:229
KOKKOS_INLINE_FUNCTION T operator[](size_t i) const
Subscript operator to get value at position i.
Definition FEMVector.hpp:211
FEMVector(size_t n, std::vector< size_t > neighbors, std::vector< Kokkos::View< size_t * > > sendIdxs, std::vector< Kokkos::View< size_t * > > recvIdxs)
Constructor taking size, neighbors, and halo exchange indices.
Definition FEMVector.hpp:4
FEMVector< T > deepCopy() const
Create a deep copy, where all the information of this vector is copied to a new one.
Definition FEMVector.hpp:234
void setHalo(T setValue)
Set the halo cells to setValue.
Definition FEMVector.hpp:152
Definition IpplExpressions.h:44
Definition IpplExpressions.h:26