Canoe
Comprehensive Atmosphere N' Ocean Engine
neighbor_exchanger.hpp
Go to the documentation of this file.
1 #ifndef SRC_EXCHANGER_NEIGHBOR_EXCHANGER_HPP_
2 #define SRC_EXCHANGER_NEIGHBOR_EXCHANGER_HPP_
3 
4 // athena
5 #include <athena/globals.hpp>
6 #include <athena/mesh/mesh.hpp>
7 
8 // canoe
9 #include <configure.hpp>
10 
11 // exchanger
12 #include "exchanger.hpp"
13 
14 #ifdef MPI_PARALLEL
15 #include <mpi.h>
16 #endif
17 
18 template <typename T>
19 void NeighborExchanger<T>::Transfer(MeshBlock const *pmb, int n) {
20  for (auto &nb : pmb->pbval->neighbor) {
21  if (nb.snb.rank == Globals::my_rank) { // on the same process
22  MeshBlock *neighbor = pmb->pmy_mesh->FindMeshBlock(nb.snb.gid);
23  auto exchanger = static_cast<NeighborExchanger<T> *>(
24  neighbor->pimpl->GetExchanger(MessageTraits<T>::name));
25  exchanger->recv_buffer_[nb.targetid].swap(send_buffer_[nb.bufid]);
26  exchanger->SetBoundaryStatus(nb.targetid, BoundaryStatus::arrived);
27  }
28 #ifdef MPI_PARALLEL
29  else { // MPI
30  int tag = MessageHelper::create_mpi_tag(nb.snb.lid, nb.targetid,
32  int ssize = send_buffer_[nb.bufid].size();
33  MPI_Isend(send_buffer_[nb.bufid].data(), ssize,
34  MessageTraits<T>::mpi_type, nb.snb.rank, tag, mpi_comm_,
35  &req_mpi_send_[nb.bufid]);
36  }
37 #endif
38  }
39 
40  int rsize, tag;
41 
42 #ifdef MPI_PARALLEL
43  MPI_Status status;
44  for (auto &nb : pmb->pbval->neighbor) {
45  if (nb.snb.rank == Globals::my_rank) continue; // local boundary received
46 
47  int tag = MessageHelper::create_mpi_tag(pmb->lid, nb.bufid,
49 
50  MPI_Probe(nb.snb.rank, tag, MPI_COMM_WORLD, &status);
51  MPI_Get_count(&status, MessageTraits<T>::mpi_type, &rsize);
52 
53  recv_buffer_[nb.bufid].resize(rsize);
54  MPI_Irecv(recv_buffer_[nb.bufid].data(), rsize, MessageTraits<T>::mpi_type,
55  nb.snb.rank, tag, mpi_comm_, &req_mpi_recv_[nb.bufid]);
56  }
57 #endif
58 }
59 
60 template <typename T>
61 void NeighborExchanger<T>::ClearBuffer(MeshBlock const *pmb) {
62  for (auto &nb : pmb->pbval->neighbor) {
63 #ifdef MPI_PARALLEL
64  if (nb.snb.rank != Globals::my_rank)
65  MPI_Wait(&req_mpi_send_[nb.bufid], MPI_STATUS_IGNORE);
66 #endif
67  }
68 }
69 
70 #endif // SRC_EXCHANGER_NEIGHBOR_EXCHANGER_HPP_
BufferType recv_buffer_[MessageTraits< T >::num_buffers]
Definition: exchanger.hpp:89
void ClearBuffer(MeshBlock const *pmb) override
Clear buffer.
void Transfer(MeshBlock const *pmb, int n=-1) override
Send and receive data.
int create_mpi_tag(int lid, int tid, std::string name)
Traits class providing Message information for class T.