2 #include <fei_CommUtils.hpp>
3 #include <fei_TemplateUtils.hpp>
6 #define fei_file "fei_CommUtils.cpp"
8 #include <fei_ErrMacros.hpp>
19 MPI_Comm_rank(comm, &local_proc);
31 MPI_Comm_size(comm, &num_procs);
37 void Barrier(MPI_Comm comm)
45 int mirrorProcs(MPI_Comm comm, std::vector<int>& toProcs, std::vector<int>& fromProcs)
49 fromProcs.push_back(0);
53 std::vector<int> tmpIntData(num_procs*3, 0);
55 int* buf = &tmpIntData[0];
56 int* recvbuf = buf+num_procs;
58 for(
unsigned i=0; i<toProcs.size(); ++i) {
62 for(
int ii=2*num_procs; ii<3*num_procs; ++ii) {
66 CHK_MPI( MPI_Reduce_scatter(buf, &(buf[num_procs]), &(buf[2*num_procs]),
67 MPI_INT, MPI_SUM, comm) );
69 int numRecvProcs = buf[num_procs];
72 std::vector<MPI_Request> mpiReqs(numRecvProcs);
75 for(
int ii=0; ii<numRecvProcs; ++ii) {
76 CHK_MPI( MPI_Irecv(&(recvbuf[ii]), 1, MPI_INT, MPI_ANY_SOURCE, tag,
77 comm, &(mpiReqs[offset++])) );
80 for(
unsigned i=0; i<toProcs.size(); ++i) {
81 CHK_MPI( MPI_Send(&(toProcs[i]), 1, MPI_INT, toProcs[i], tag, comm) );
85 for(
int ii=0; ii<numRecvProcs; ++ii) {
87 MPI_Waitany(numRecvProcs, &mpiReqs[0], &index, &status);
88 fromProcs.push_back(status.MPI_SOURCE);
91 std::sort(fromProcs.begin(), fromProcs.end());
107 if (numP < 2)
return(0);
109 std::vector<int> buf(numP*2, 0);
111 int numInProcs = inPattern->getMap().size();
112 std::vector<int> inProcs(numInProcs);
115 std::vector<int> outProcs;
118 if (err != 0) ERReturn(-1);
120 std::vector<int> recvbuf(outProcs.size(), 0);
122 outPattern =
new comm_map(0,1);
124 MPI_Datatype mpi_ttype = fei::mpiTraits<int>::mpi_type();
129 std::vector<MPI_Request> mpiReqs(outProcs.size());
130 std::vector<MPI_Status> mpiStss(outProcs.size());
131 MPI_Request* requests = &mpiReqs[0];
132 MPI_Status* statuses = &mpiStss[0];
134 int firsttag = 11117;
136 int* outProcsPtr = &outProcs[0];
137 for(
unsigned i=0; i<outProcs.size(); ++i) {
138 if (MPI_Irecv(&(recvbuf[i]), 1, MPI_INT, outProcsPtr[i], firsttag,
139 comm, &requests[offset++]) != MPI_SUCCESS) ERReturn(-1);
143 comm_map::map_type::iterator
144 in_iter = in_row_map.begin(),
145 in_end = in_row_map.end();
147 int* inProcsPtr = &inProcs[0];
148 for(
int ii=0; in_iter!= in_end; ++in_iter, ++ii) {
150 buf[ii] = in_row->size();
151 if (MPI_Send(&(buf[ii]), 1, MPI_INT, inProcsPtr[ii], firsttag,
152 comm) != MPI_SUCCESS) ERReturn(-1);
155 int numOutProcs = outProcs.size();
157 MPI_Waitall(numOutProcs, requests, statuses);
158 std::vector<int> lengths(numOutProcs);
159 int totalRecvLen = 0;
161 for(
int ii=0; ii<numOutProcs; ++ii) {
162 if (recvbuf[ii] > 0) {
163 lengths[offset++] = recvbuf[ii];
164 totalRecvLen += recvbuf[ii];
170 std::vector<int> recvData(totalRecvLen, 999999);
174 for(
int ii=0; ii<numOutProcs; ++ii) {
175 CHK_MPI(MPI_Irecv(&(recvData[offset]), lengths[ii], mpi_ttype,
176 outProcs[ii], tag2, comm, &requests[ii]) );
177 offset += lengths[ii];
180 std::vector<int> sendList;
182 in_iter = in_row_map.begin();
184 for(
int ii=0; in_iter != in_end; ++in_iter,++ii) {
185 if (inProcs[ii] == localP) {
188 sendList.resize(in_iter->second->size());
191 CHK_MPI(MPI_Send(&sendList[0], sendList.size(), mpi_ttype,
192 inProcs[ii], tag2, comm) );
196 for(
int ii=0; ii<numOutProcs; ++ii) {
197 MPI_Wait(&requests[ii], &statuses[ii]);
203 for(
int ii=0; ii<numOutProcs; ii++) {
204 outPattern->addIndices(outProcs[ii], lengths[ii],
205 &(recvData[offset]));
206 offset += lengths[ii];
216 const std::vector<int>& sendProcs,
217 std::vector<int>& sendData,
218 const std::vector<int>& recvProcs,
219 std::vector<int>& recvData)
221 if (sendProcs.size() == 0 && recvProcs.size() == 0)
return(0);
222 if (sendProcs.size() != sendData.size())
return(-1);
224 recvData.resize(recvProcs.size());
225 std::vector<MPI_Request> mpiReqs;
226 mpiReqs.resize(recvProcs.size());
229 MPI_Datatype mpi_dtype = MPI_INT;
234 int numRecvProcs = recvProcs.size();
236 for(
unsigned i=0; i<recvProcs.size(); ++i) {
237 if (recvProcs[i] == localProc) {--numRecvProcs;
continue; }
239 CHK_MPI( MPI_Irecv(&(recvData[i]), 1, mpi_dtype, recvProcs[i], tag,
240 comm, &mpiReqs[req_offset++]) );
245 for(
unsigned i=0; i<sendProcs.size(); ++i) {
246 if (sendProcs[i] == localProc)
continue;
248 CHK_MPI( MPI_Send(&(sendData[i]), 1, mpi_dtype,
249 sendProcs[i], tag, comm) );
254 for(
int ii=0; ii<numRecvProcs; ++ii) {
257 CHK_MPI( MPI_Waitany(numRecvProcs, &mpiReqs[0], &index, &status) );
265 int Allreduce(MPI_Comm comm,
bool localBool,
bool& globalBool)
268 int localInt = localBool ? 1 : 0;
271 CHK_MPI( MPI_Allreduce(&localInt, &globalInt, 1, MPI_INT, MPI_MAX, comm) );
273 globalBool = globalInt==1 ?
true :
false;
275 globalBool = localBool;
int mirrorCommPattern(MPI_Comm comm, comm_map *inPattern, comm_map *&outPattern)
void copySetToArray(const SET_TYPE &set_obj, int lenList, int *list)
void copyKeysToVector(const MAP_TYPE &map_obj, std::vector< int > &keyvector)
int mirrorProcs(MPI_Comm comm, std::vector< int > &toProcs, std::vector< int > &fromProcs)
int Allreduce(MPI_Comm comm, bool localBool, bool &globalBool)
int exchangeIntData(MPI_Comm comm, const std::vector< int > &sendProcs, std::vector< int > &sendData, const std::vector< int > &recvProcs, std::vector< int > &recvData)
int localProc(MPI_Comm comm)
int numProcs(MPI_Comm comm)