37 #ifndef HALOEXCHANGE_H
38 #define HALOEXCHANGE_H
46 template <
typename DATATYPE,
int block>
48 const std::vector< std::vector<index_t> > &send,
49 const std::vector< std::vector<index_t> > &recv,
50 std::vector<DATATYPE> &vec){
52 MPI_Comm_size(comm, &num_processes);
56 assert(num_processes==send.size());
57 assert(num_processes==recv.size());
60 MPI_Comm_rank(comm, &rank);
65 std::vector<MPI_Request> request(num_processes*2);
68 std::vector< std::vector<DATATYPE> > recv_buff(num_processes);
69 for(
int i=0;i<num_processes;i++){
70 if((i==rank)||(recv[i].size()==0)){
71 request[i] = MPI_REQUEST_NULL;
73 recv_buff[i].resize(recv[i].size()*block);
74 MPI_Irecv(&(recv_buff[i][0]), recv_buff[i].size(), wrap.
mpi_type, i, 0, comm, &(request[i]));
79 std::vector< std::vector<DATATYPE> > send_buff(num_processes);
80 for(
int i=0;i<num_processes;i++){
81 if((i==rank)||(send[i].size()==0)){
82 request[num_processes+i] = MPI_REQUEST_NULL;
84 for(
typename std::vector<index_t>::const_iterator it=send[i].begin();it!=send[i].end();++it)
85 for(
int j=0;j<block;j++){
86 send_buff[i].push_back(vec[(*it)*block+j]);
88 MPI_Isend(&(send_buff[i][0]), send_buff[i].size(), wrap.
mpi_type, i, 0, comm, &(request[num_processes+i]));
92 std::vector<MPI_Status> status(num_processes*2);
93 MPI_Waitall(num_processes, &(request[0]), &(status[0]));
94 MPI_Waitall(num_processes, &(request[num_processes]), &(status[num_processes]));
96 for(
int i=0;i<num_processes;i++){
98 for(
typename std::vector<index_t>::const_iterator it=recv[i].begin();it!=recv[i].end();++it, ++k)
99 for(
int j=0;j<block;j++)
100 vec[(*it)*block+j] = recv_buff[i][k*block+j];
106 template <
typename DATATYPE,
int block0,
int block1>
108 const std::vector< std::vector<index_t> > &send,
109 const std::vector< std::vector<index_t> > &recv,
110 std::vector<DATATYPE> &vec0, std::vector<DATATYPE> &vec1){
112 MPI_Comm_size(comm, &num_processes);
116 assert(num_processes==send.size());
117 assert(num_processes==recv.size());
120 MPI_Comm_rank(comm, &rank);
125 std::vector<MPI_Request> request(num_processes*2);
128 std::vector< std::vector<DATATYPE> > recv_buff(num_processes);
129 for(
int i=0;i<num_processes;i++){
130 int msg_size = recv[i].size()*(block0+block1);
131 if((i==rank)||(msg_size==0)){
132 request[i] = MPI_REQUEST_NULL;
134 recv_buff[i].resize(msg_size);
135 MPI_Irecv(&(recv_buff[i][0]), msg_size, wrap.
mpi_type, i, 0, comm, &(request[i]));
140 std::vector< std::vector<DATATYPE> > send_buff(num_processes);
141 for(
int i=0;i<num_processes;i++){
142 if((i==rank)||(send[i].size()==0)){
143 request[num_processes+i] = MPI_REQUEST_NULL;
145 for(
typename std::vector<index_t>::const_iterator it=send[i].begin();it!=send[i].end();++it){
146 for(
int j=0;j<block0;j++){
147 send_buff[i].push_back(vec0[(*it)*block0+j]);
149 for(
int j=0;j<block1;j++){
150 send_buff[i].push_back(vec1[(*it)*block1+j]);
153 MPI_Isend(&(send_buff[i][0]), send_buff[i].size(), wrap.
mpi_type, i, 0, comm, &(request[num_processes+i]));
157 std::vector<MPI_Status> status(num_processes*2);
158 MPI_Waitall(num_processes, &(request[0]), &(status[0]));
159 MPI_Waitall(num_processes, &(request[num_processes]), &(status[num_processes]));
161 int block01 = block0+block1;
162 for(
int i=0;i<num_processes;i++){
164 for(
typename std::vector<index_t>::const_iterator it=recv[i].begin();it!=recv[i].end();++it, ++k){
165 for(
int j=0;j<block0;j++)
166 vec0[(*it)*block0+j] = recv_buff[i][k*block01+j];
167 for(
int j=0;j<block1;j++)
168 vec1[(*it)*block1+j] = recv_buff[i][k*block01+block0+j];
void halo_update(MPI_Comm comm, const std::vector< std::vector< index_t > > &send, const std::vector< std::vector< index_t > > &recv, std::vector< DATATYPE > &vec)
const MPI_Datatype mpi_type