12 #include "../config/config.hpp"
35 group_lproc(gt.group_lproc)
37 gt.groupmaster_lproc.
Copy(groupmaster_lproc);
38 gt.lproc_proc.
Copy(lproc_proc);
39 gt.group_mgroup.
Copy(group_mgroup);
42 void GroupTopology::ProcToLProc()
45 MPI_Comm_size(MyComm, &NRanks);
47 map<int, int> proc_lproc;
49 int lproc_counter = 0;
52 const pair<const int, int> p(group_lproc.
GetJ()[i], lproc_counter);
53 if (proc_lproc.insert(p).second)
60 lproc_proc.
SetSize(lproc_counter);
61 for (map<int, int>::iterator it = proc_lproc.begin();
62 it != proc_lproc.end(); ++it)
64 lproc_proc[it->second] = it->first;
69 group_lproc.
GetJ()[i] = proc_lproc[group_lproc.
GetJ()[i]];
72 for (
int i = 0; i <
NGroups(); i++)
74 groupmaster_lproc[i] = proc_lproc[groupmaster_lproc[i]];
82 Table group_mgroupandproc;
85 for (
int i = 0; i <
NGroups(); i++)
87 int j = group_mgroupandproc.
GetI()[i];
88 group_mgroupandproc.
GetI()[i+1] = j + group_lproc.
RowSize(i) + 1;
89 group_mgroupandproc.
GetJ()[j] = i;
91 for (
int k = group_lproc.
GetI()[i];
92 j < group_mgroupandproc.
GetI()[i+1]; j++, k++)
94 group_mgroupandproc.
GetJ()[j] = group_lproc.
GetJ()[k];
102 for (
int i = 0; i <
NGroups(); i++)
117 int send_counter = 0;
118 int recv_counter = 0;
119 for (
int i = 1; i <
NGroups(); i++)
120 if (groupmaster_lproc[i] != 0)
126 send_counter += group_lproc.
RowSize(i)-1;
129 MPI_Request *requests =
new MPI_Request[send_counter];
130 MPI_Status *statuses =
new MPI_Status[send_counter];
132 int max_recv_size = 0;
134 for (
int i = 1; i <
NGroups(); i++)
136 if (groupmaster_lproc[i] == 0)
140 for (
int j = group_lproc.
GetI()[i];
141 j < group_lproc.
GetI()[i+1]; j++)
143 if (group_lproc.
GetJ()[j] != 0)
145 MPI_Isend(group_mgroupandproc.
GetRow(i),
146 group_mgroupandproc.
RowSize(i),
148 lproc_proc[group_lproc.
GetJ()[j]],
151 &requests[send_counter]);
157 if (max_recv_size < group_lproc.
RowSize(i))
159 max_recv_size = group_lproc.
RowSize(i);
165 if (recv_counter > 0)
169 int *recv_buf =
new int[max_recv_size];
170 for ( ; recv_counter > 0; recv_counter--)
172 MPI_Recv(recv_buf, max_recv_size, MPI_INT,
173 MPI_ANY_SOURCE, mpitag, MyComm, &status);
175 MPI_Get_count(&status, MPI_INT, &count);
177 group.
Recreate(count-1, recv_buf+1);
178 int g = groups.
Lookup(group);
179 group_mgroup[g] = recv_buf[0];
181 if (lproc_proc[groupmaster_lproc[g]] != status.MPI_SOURCE)
183 cerr <<
"\n\n\nGroupTopology::GroupTopology: "
184 <<
MyRank() <<
": ERROR\n\n\n" << endl;
191 MPI_Waitall(send_counter, requests, statuses);
214 for (
int i = 0; i < ldof_group.
Size(); i++)
216 int group = ldof_group[i];
224 for (
int i = 0; i < ldof_group.
Size(); i++)
226 int group = ldof_group[i];
239 int request_counter = 0;
241 for (
int gr = 1; gr < group_ldof.
Size(); gr++)
242 if (group_ldof.
RowSize(gr) != 0)
254 request_counter += gr_requests;
255 group_buf_size += gr_requests * group_ldof.
RowSize(gr);
258 requests =
new MPI_Request[request_counter];
259 statuses =
new MPI_Status[request_counter];
265 if (group_buf_size == 0)
270 group_buf.
SetSize(group_buf_size*
sizeof(T));
271 T *buf = (T *)group_buf.
GetData();
273 int i, gr, request_counter = 0;
275 for (gr = 1; gr < group_ldof.
Size(); gr++)
277 const int nldofs = group_ldof.
RowSize(gr);
293 &requests[request_counter]);
299 const int *ldofs = group_ldof.
GetRow(gr);
300 for (i = 0; i < nldofs; i++)
302 buf[i] = ldata[ldofs[i]];
306 const int *nbs = gtopo.
GetGroup(gr);
307 for (i = 0; i < gs; i++)
317 &requests[request_counter]);
325 MPI_Waitall(request_counter, requests, statuses);
328 buf = (T *)group_buf.
GetData();
329 for (gr = 1; gr < group_ldof.
Size(); gr++)
331 const int nldofs = group_ldof.
RowSize(gr);
341 const int *ldofs = group_ldof.
GetRow(gr);
342 for (i = 0; i < nldofs; i++)
344 ldata[ldofs[i]] = buf[i];
354 if (group_buf_size == 0)
359 int i, gr, request_counter = 0;
362 group_buf.
SetSize(group_buf_size*
sizeof(T));
365 for (gr = 1; gr < group_ldof.
Size(); gr++)
379 for (i = 0; i < opd.
nldofs; i++)
390 &requests[request_counter]);
397 const int *nbs = gtopo.
GetGroup(gr);
398 for (i = 0; i < gs; i++)
408 &requests[request_counter]);
416 MPI_Waitall(request_counter, requests, statuses);
420 for (gr = 1; gr < group_ldof.
Size(); gr++)
447 for (
int i = 0; i < opd.
nldofs; i++)
450 for (
int j = 0; j < opd.
nb; j++)
461 for (
int i = 0; i < opd.
nldofs; i++)
464 for (
int j = 0; j < opd.
nb; j++)
479 for (
int i = 0; i < opd.
nldofs; i++)
482 for (
int j = 0; j < opd.
nb; j++)
497 for (
int i = 0; i < opd.
nldofs; i++)
500 for (
int j = 0; j < opd.
nb; j++)
517 template void GroupCommunicator::Bcast<int>(
int *);
518 template void GroupCommunicator::Reduce<int>(
int *, void (*)(OpData<int>));
520 template void GroupCommunicator::Bcast<double>(
double *);
521 template void GroupCommunicator::Reduce<double>(
522 double *, void (*)(OpData<double>));
527 template void GroupCommunicator::Sum<int>(OpData<int>);
528 template void GroupCommunicator::Min<int>(OpData<int>);
529 template void GroupCommunicator::Max<int>(OpData<int>);
530 template void GroupCommunicator::BitOR<int>(OpData<int>);
532 template void GroupCommunicator::Sum<double>(OpData<double>);
533 template void GroupCommunicator::Min<double>(OpData<double>);
534 template void GroupCommunicator::Max<double>(OpData<double>);
538 static void DebugRankCoords(
int** coords,
int dim,
int size)
540 for (
int i = 0; i < size; i++)
542 std::cout <<
"Rank " << i <<
" coords: ";
543 for (
int j = 0; j <
dim; j++)
545 std::cout << coords[i][j] <<
" ";
553 CompareCoords(
int coord) : coord(coord) {}
556 bool operator()(
int*
const &a,
int*
const &b)
const
557 {
return a[coord] < b[coord]; }
564 bool all_same =
true;
565 for (
int i = 1; i < size && all_same; i++)
567 for (
int j = 0; j <
dim; j++)
569 if (coords[i][j] != coords[0][j]) { all_same =
false;
break; }
572 if (all_same) {
return; }
575 std::sort(coords, coords + size, CompareCoords(d));
576 int next = (d + 1) % dim;
578 if (coords[0][d] < coords[size-1][d])
581 KdTreeSort(coords + size/2, next, dim, size - size/2);
596 MPI_Comm_rank(comm, &rank);
597 MPI_Comm_size(comm, &size);
600 MPIX_Torus_ndims(&dim);
602 int* mycoords =
new int[dim + 1];
603 MPIX_Rank2torus(rank, mycoords);
605 MPI_Send(mycoords, dim, MPI_INT, 0, 111, comm);
610 int** coords =
new int*[size];
611 for (
int i = 0; i < size; i++)
613 coords[i] =
new int[dim + 1];
615 MPI_Recv(coords[i], dim, MPI_INT, i, 111, comm, &status);
622 for (
int i = 0; i < size; i++)
624 MPI_Send(&coords[i][dim], 1, MPI_INT, i, 112, comm);
631 MPI_Recv(&new_rank, 1, MPI_INT, 0, 112, comm, &status);
634 MPI_Comm_split(comm, 0, new_rank, &new_comm);
int Lookup(IntegerSet &s)
int GetGroupMasterRank(int g) const
void Create(ListOfIntegerSets &groups, int mpitag)
int Size() const
Logical size of the array.
void Recreate(const int n, const int *p)
int GetGroupMasterGroup(int g) const
GroupCommunicator(GroupTopology >)
Helper struct to convert a C++ type to an MPI type.
MPI_Comm ReorderRanksZCurve(MPI_Comm comm)
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
void Copy(Array ©) const
Create a copy of the current array.
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 Size_of_connections() const
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 KdTreeSort(int **coords, int d, int dim, int size)
void Create(Array< int > &ldof_group)
static void BitOR(OpData< T >)
Reduce operation bitwise OR, instantiated for int only.