12 #include "../config/config.hpp"
28 void GroupTopology::ProcToLProc()
31 MPI_Comm_size(MyComm, &NRanks);
33 Array<int> proc_lproc(NRanks);
36 int lproc_counter = 0;
37 for (
int i = 0; i < group_lproc.Size_of_connections(); i++)
38 if (proc_lproc[group_lproc.GetJ()[i]] < 0)
39 proc_lproc[group_lproc.GetJ()[i]] = lproc_counter++;
42 lproc_proc.SetSize(lproc_counter);
43 for (
int i = 0; i < NRanks; i++)
44 if (proc_lproc[i] >= 0)
45 lproc_proc[proc_lproc[i]] = i;
47 for (
int i = 0; i < group_lproc.Size_of_connections(); i++)
48 group_lproc.GetJ()[i] = proc_lproc[group_lproc.GetJ()[i]];
50 for (
int i = 0; i < NGroups(); i++)
51 groupmaster_lproc[i] = proc_lproc[groupmaster_lproc[i]];
58 Table group_mgroupandproc;
59 group_mgroupandproc.
SetDims(NGroups(),
60 group_lproc.Size_of_connections() + NGroups());
61 for (
int i = 0; i < NGroups(); i++)
63 int j = group_mgroupandproc.
GetI()[i];
64 group_mgroupandproc.
GetI()[i+1] = j + group_lproc.RowSize(i) + 1;
65 group_mgroupandproc.
GetJ()[j] = i;
67 for (
int k = group_lproc.GetI()[i];
68 j < group_mgroupandproc.
GetI()[i+1]; j++, k++)
69 group_mgroupandproc.
GetJ()[j] = group_lproc.GetJ()[k];
73 groupmaster_lproc.SetSize(NGroups());
76 for (
int i = 0; i < NGroups(); i++)
87 group_mgroup.SetSize(NGroups());
91 for (
int i = 1; i < NGroups(); i++)
92 if (groupmaster_lproc[i] != 0)
95 send_counter += group_lproc.RowSize(i)-1;
97 MPI_Request *requests =
new MPI_Request[send_counter];
98 MPI_Status *statuses =
new MPI_Status[send_counter];
100 int max_recv_size = 0;
102 for (
int i = 1; i < NGroups(); i++)
104 if (groupmaster_lproc[i] == 0)
108 for (
int j = group_lproc.GetI()[i];
109 j < group_lproc.GetI()[i+1]; j++)
111 if (group_lproc.GetJ()[j] != 0)
113 MPI_Isend(group_mgroupandproc.
GetRow(i),
114 group_mgroupandproc.
RowSize(i),
116 lproc_proc[group_lproc.GetJ()[j]],
119 &requests[send_counter]);
125 if (max_recv_size < group_lproc.RowSize(i))
126 max_recv_size = group_lproc.RowSize(i);
131 if (recv_counter > 0)
135 int *recv_buf =
new int[max_recv_size];
136 for ( ; recv_counter > 0; recv_counter--)
138 MPI_Recv(recv_buf, max_recv_size, MPI_INT,
139 MPI_ANY_SOURCE, mpitag, MyComm, &status);
141 MPI_Get_count(&status, MPI_INT, &count);
143 group.
Recreate(count-1, recv_buf+1);
144 int g = groups.
Lookup(group);
145 group_mgroup[g] = recv_buf[0];
147 if (lproc_proc[groupmaster_lproc[g]] != status.MPI_SOURCE)
149 cerr <<
"\n\n\nGroupTopology::GroupTopology: "
150 << MyRank() <<
": ERROR\n\n\n" << endl;
157 MPI_Waitall(send_counter, requests, statuses);
175 for (
int i = 0; i < ldof_group.
Size(); i++)
177 int group = ldof_group[i];
183 for (
int i = 0; i < ldof_group.
Size(); i++)
185 int group = ldof_group[i];
196 int request_counter = 0;
198 for (
int gr = 1; gr < group_ldof.
Size(); gr++)
199 if (group_ldof.
RowSize(gr) != 0)
207 request_counter += gr_requests;
208 group_buf_size += gr_requests * group_ldof.
RowSize(gr);
211 requests =
new MPI_Request[request_counter];
212 statuses =
new MPI_Status[request_counter];
218 if (group_buf_size == 0)
221 group_buf.
SetSize(group_buf_size*
sizeof(T));
222 T *buf = (T *)group_buf.
GetData();
224 int i, gr, request_counter = 0;
226 for (gr = 1; gr < group_ldof.
Size(); gr++)
228 const int nldofs = group_ldof.
RowSize(gr);
238 Get_MPI_Datatype<T>(),
242 &requests[request_counter]);
248 const int *ldofs = group_ldof.
GetRow(gr);
249 for (i = 0; i < nldofs; i++)
250 buf[i] = ldata[ldofs[i]];
253 const int *nbs = gtopo.
GetGroup(gr);
254 for (i = 0; i < gs; i++)
260 Get_MPI_Datatype<T>(),
264 &requests[request_counter]);
272 MPI_Waitall(request_counter, requests, statuses);
275 buf = (T *)group_buf.
GetData();
276 for (gr = 1; gr < group_ldof.
Size(); gr++)
278 const int nldofs = group_ldof.
RowSize(gr);
286 const int *ldofs = group_ldof.
GetRow(gr);
287 for (i = 0; i < nldofs; i++)
288 ldata[ldofs[i]] = buf[i];
297 if (group_buf_size == 0)
300 int i, gr, request_counter = 0;
303 group_buf.
SetSize(group_buf_size*
sizeof(T));
306 for (gr = 1; gr < group_ldof.
Size(); gr++)
318 for (i = 0; i < opd.
nldofs; i++)
323 Get_MPI_Datatype<T>(),
327 &requests[request_counter]);
334 const int *nbs = gtopo.
GetGroup(gr);
335 for (i = 0; i < gs; i++)
341 Get_MPI_Datatype<T>(),
345 &requests[request_counter]);
353 MPI_Waitall(request_counter, requests, statuses);
357 for (gr = 1; gr < group_ldof.
Size(); gr++)
382 for (
int i = 0; i < opd.
nldofs; i++)
385 for (
int j = 0; j < opd.
nb; j++)
394 for (
int i = 0; i < opd.
nldofs; i++)
397 for (
int j = 0; j < opd.
nb; j++)
410 for (
int i = 0; i < opd.
nldofs; i++)
413 for (
int j = 0; j < opd.
nb; j++)
426 for (
int i = 0; i < opd.
nldofs; i++)
429 for (
int j = 0; j < opd.
nb; j++)
442 template <>
inline MPI_Datatype GroupCommunicator::Get_MPI_Datatype<int>()
447 template <>
inline MPI_Datatype GroupCommunicator::Get_MPI_Datatype<double>()
453 template void GroupCommunicator::Bcast<int>(
int *);
454 template void GroupCommunicator::Reduce<int>(
int *, void (*)(OpData<int>));
456 template void GroupCommunicator::Bcast<double>(
double *);
457 template void GroupCommunicator::Reduce<double>(
458 double *, void (*)(OpData<double>));
461 template void GroupCommunicator::Sum<int>(OpData<int>);
462 template void GroupCommunicator::Min<int>(OpData<int>);
463 template void GroupCommunicator::Max<int>(OpData<int>);
464 template void GroupCommunicator::BitOR<int>(OpData<int>);
466 template void GroupCommunicator::Sum<double>(OpData<double>);
467 template void GroupCommunicator::Min<double>(OpData<double>);
468 template void GroupCommunicator::Max<double>(OpData<double>);
int Lookup(IntegerSet &s)
int GetGroupMasterRank(int g) const
int Size() const
Logical size of the array.
void Recreate(const int n, const int *p)
int GetGroupMasterGroup(int g) const
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
int GetGroupSize(int g) const
void SetDims(int rows, int nnz)
const int * GetGroup(int g) const
T * GetData()
Returns the data.
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
int PickElementInSet(int i)
bool IAmMaster(int g) const
static void Sum(OpData< T >)
Reduce operation Sum, instantiated for int and double.
void Finalize()
Allocate internal buffers after the GroupLDofTable is defined.
void AddConnection(int r, int c)
static void Min(OpData< T >)
Reduce operation Min, instantiated for int and double.
int Size() const
Returns the number of TYPE I elements.
int GetNeighborRank(int i) const
static void Max(OpData< T >)
Reduce operation Max, instantiated for int and double.
void AddAColumnInRow(int r)
void mfem_error(const char *msg)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
void Reduce(T *ldata, void(*Op)(OpData< T >))
void Create(Array< int > &ldof_group)
static void BitOR(OpData< T >)
Reduce operation bitwise OR, instantiated for int only.