31 tLocalMatStruct::const_iterator mat_begin, tLocalMatStruct::const_iterator mat_end,
int nPart,
33 std::string metisType =
"KWAY",
int metisNcuts = 3,
int metisUfactor = 5,
int metisSeed = 0)
35 idx_t nCell = _METIS::indexToIdx(size_t_to_signed<index>(mat_end - mat_begin));
36 idx_t nCon{1}, options[METIS_NOPTIONS];
37 METIS_SetDefaultOptions(options);
39 options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_CUT;
40 options[METIS_OPTION_CTYPE] = METIS_CTYPE_SHEM;
41 options[METIS_OPTION_IPTYPE] = METIS_IPTYPE_GROW;
42 options[METIS_OPTION_RTYPE] = METIS_RTYPE_FM;
44 options[METIS_OPTION_NCUTS] = std::max(metisNcuts, 1);
45 options[METIS_OPTION_NITER] = 10;
47 options[METIS_OPTION_UFACTOR] = metisUfactor;
48 options[METIS_OPTION_MINCONN] = 1;
49 options[METIS_OPTION_CONTIG] = 1;
50 options[METIS_OPTION_SEED] = metisSeed;
51 options[METIS_OPTION_NUMBERING] = 0;
55 auto &cell2cellFaceV = mat_begin;
59 std::vector<idx_t> adjncy, xadj;
60 xadj.resize(nCell + 1);
62 for (idx_t iC = 0; iC < nCell; iC++)
65 for (
auto iCOther : cell2cellFaceV[iC])
67 index iLocal = iCOther - ind_offset;
68 if (iLocal >= 0 && iLocal < nCell)
71 xadj[iC + 1] = xadj[iC] + count;
73 adjncy.resize(xadj.back());
74 for (idx_t iC = 0; iC < nCell; iC++)
77 for (
auto iCOther : cell2cellFaceV[iC])
79 index iLocal = iCOther - ind_offset;
80 if (iLocal >= 0 && iLocal < nCell)
81 adjncy[pos++] = _METIS::indexToIdx(iLocal);
86 std::vector<idx_t> partOut(nCell);
89 if (metisType ==
"RB")
90 ret = METIS_PartGraphRecursive(
91 &nCell, &nCon, xadj.data(), adjncy.data(), NULL, NULL, NULL,
92 &nPart, NULL, NULL, options, &objval, partOut.data());
93 else if (metisType ==
"KWAY")
94 ret = METIS_PartGraphKway(
95 &nCell, &nCon, xadj.data(), adjncy.data(), NULL, NULL, NULL,
96 &nPart, NULL, NULL, options, &objval, partOut.data());
98 DNDS_assert_info(ret == METIS_OK, fmt::format(
"Metis return not ok, [{}]", ret));
105 idx_t nCell = _METIS::indexToIdx(size_t_to_signed<index>(mat.size()));
106 idx_t nCon{1}, options[METIS_NOPTIONS];
107 METIS_SetDefaultOptions(options);
109 options[METIS_OPTION_CTYPE] = METIS_CTYPE_SHEM;
110 options[METIS_OPTION_RTYPE] = METIS_RTYPE_FM;
111 options[METIS_OPTION_IPTYPE] = METIS_IPTYPE_EDGE;
112 options[METIS_OPTION_RTYPE] = METIS_RTYPE_SEP1SIDED;
113 options[METIS_OPTION_NSEPS] = 1;
114 options[METIS_OPTION_NITER] = 10;
115 options[METIS_OPTION_UFACTOR] = 30;
116 options[METIS_OPTION_COMPRESS] = 0;
118 options[METIS_OPTION_SEED] = 0;
119 options[METIS_OPTION_PFACTOR] = 0;
120 options[METIS_OPTION_NUMBERING] = 0;
123 const std::vector<std::vector<index>> &cell2cellFaceV = mat;
124 std::vector<idx_t> adjncy, xadj, perm, iPerm;
125 xadj.resize(nCell + 1);
127 for (idx_t iC = 0; iC < nCell; iC++)
128 xadj[iC + 1] = signedIntSafeAdd<idx_t>(xadj[iC], size_t_to_signed<idx_t>(cell2cellFaceV[iC].size()));
129 adjncy.resize(xadj.back());
130 for (idx_t iC = 0; iC < nCell; iC++)
131 std::copy(cell2cellFaceV[iC].begin(), cell2cellFaceV[iC].end(), adjncy.begin() + xadj[iC]);
135 int ret = METIS_NodeND(&nCell, xadj.data(), adjncy.data(), NULL, options, perm.data(), iPerm.data());
136 DNDS_assert_info(ret == METIS_OK, fmt::format(
"Metis return not ok, [{}]", ret));
138 std::vector<index> localFillOrderingNew2Old, localFillOrderingOld2New;
140 localFillOrderingNew2Old.resize(nCell);
141 localFillOrderingOld2New.resize(nCell);
142 for (
index i = 0; i < nCell; i++)
144 localFillOrderingNew2Old[i] = perm[i];
145 localFillOrderingOld2New[i] = iPerm[i];
148 return {localFillOrderingNew2Old, localFillOrderingOld2New};
153 std::vector<index> localFillOrderingNew2Old, localFillOrderingOld2New;
154 using namespace boost;
155 using Graph = adjacency_list<vecS, vecS, directedS>;
156 Graph cell2cellG(mat.size());
157 const std::vector<std::vector<index>> &cell2cellFaceV = mat;
158 for (
index iCell = 0; iCell < size_t_to_signed<index>(mat.size()); iCell++)
159 for (
auto iCOther : cell2cellFaceV[iCell])
160 add_edge(iCell, iCOther, cell2cellG);
161 std::vector<index> supernodeSizes(mat.size(), 1), degree(mat.size(), 0);
162 localFillOrderingNew2Old.resize(mat.size(), 0);
163 localFillOrderingOld2New.resize(mat.size(), 0);
164 boost::property_map<Graph, vertex_index_t>::type
id = get(vertex_index, cell2cellG);
165 minimum_degree_ordering(
167 make_iterator_property_map(degree.data(),
id, degree[0]),
168 localFillOrderingOld2New.data(),
169 localFillOrderingNew2Old.data(),
170 make_iterator_property_map(supernodeSizes.data(),
id, supernodeSizes[0]),
173 return {localFillOrderingNew2Old, localFillOrderingOld2New};
178 std::vector<index> localFillOrderingNew2Old, localFillOrderingOld2New;
179 using namespace boost;
180 using Graph = adjacency_list<vecS, vecS, undirectedS, property<vertex_color_t, default_color_type, property<vertex_degree_t, int>>>;
181 using Vertex = graph_traits<Graph>::vertex_descriptor;
183 Graph cell2cellG(mat.size());
184 const std::vector<std::vector<index>> &cell2cellFaceV = mat;
186 for (
index iCell = 0; iCell < size_t_to_signed<index>(mat.size()); iCell++)
187 for (
auto iCOther : cell2cellFaceV[iCell])
188 add_edge(iCell, iCOther, cell2cellG), bandWidthOld = std::max(bandWidthOld, std::abs(iCell - iCOther));
189 localFillOrderingNew2Old.resize(mat.size(), 0);
190 localFillOrderingOld2New.resize(mat.size(), 0);
191 Vertex startVert = vertex(0, cell2cellG);
192 cuthill_mckee_ordering(cell2cellG, startVert, localFillOrderingNew2Old.rbegin(),
193 get(vertex_color, cell2cellG), get(vertex_degree, cell2cellG));
194 std::unordered_set<index> __checkOrder;
195 for (
auto v : localFillOrderingNew2Old)
197 DNDS_assert_info(__checkOrder.size() == localFillOrderingNew2Old.size(),
"The output of boost::cuthill_mckee_ordering is invalid!");
199 for (
index iCell = 0; iCell < size_t_to_signed<index>(mat.size()); iCell++)
200 localFillOrderingOld2New[localFillOrderingNew2Old[iCell]] = iCell;
201 for (
auto v : localFillOrderingOld2New)
202 DNDS_assert(
v < size_t_to_signed<index>(mat.size()) &&
v >= 0);
204 for (
index iCell = 0; iCell < size_t_to_signed<index>(mat.size()); iCell++)
205 for (
auto iCOther : cell2cellFaceV[iCell])
206 bandWidthNew = std::max(bandWidthNew, std::abs(localFillOrderingOld2New[iCell] - localFillOrderingOld2New[iCOther]));
208 return {localFillOrderingNew2Old, localFillOrderingOld2New};
280 tLocalMatStruct::const_iterator mat_begin, tLocalMatStruct::const_iterator mat_end,
284 std::vector<index> localFillOrderingNew2Old, localFillOrderingOld2New;
297 index mat_size = mat_end - mat_begin;
299 for (
index iCell = 0; iCell < size_t_to_signed<index>(mat_size); iCell++)
300 for (
auto iCOther : mat_begin[iCell])
301 bandWidthOld = std::max(bandWidthOld, std::abs(iCell + offset - iCOther));
303 localFillOrderingNew2Old.resize(mat_size, 0);
304 localFillOrderingOld2New.resize(mat_size, 0);
305 auto graphFunctor = [&](
index i)
311 int ret = graph.CheckAdj();
316 return localFillOrderingOld2New.at(i);
319 for (
auto &
v : localFillOrderingOld2New)
320 v = localFillOrderingOld2New.size() - 1 -
v;
322 std::unordered_set<index>
324 for (
auto v : localFillOrderingOld2New)
325 DNDS_assert(
v < size_t_to_signed<index>(mat_size) &&
v >= 0), __checkOrder.insert(
v);
326 DNDS_check_throw_info(__checkOrder.size() == localFillOrderingOld2New.size(),
"The output of CorrectRCM::CuthillMcKeeOrdering is invalid!");
328 for (
index iCell = 0; iCell < size_t_to_signed<index>(mat_size); iCell++)
329 localFillOrderingNew2Old[localFillOrderingOld2New[iCell]] = iCell;
330 for (
auto v : localFillOrderingNew2Old)
331 DNDS_assert(
v < size_t_to_signed<index>(mat_size) &&
v >= 0);
333 for (
index iCell = 0; iCell < size_t_to_signed<index>(mat_size); iCell++)
334 for (
auto iCOther : mat_begin[iCell])
335 bandWidthNew = std::max(bandWidthNew, std::abs(localFillOrderingOld2New[iCell] - localFillOrderingOld2New.at(iCOther - offset)));
337 return {localFillOrderingNew2Old, localFillOrderingOld2New};
std::vector< index > ReorderSerialAdj_PartitionMetisC(tLocalMatStruct::iterator mat_begin, tLocalMatStruct::iterator mat_end, std::vector< index >::iterator i_new2old_begin, std::vector< index >::iterator i_new2old_end, int nParts, index ind_offset, bool do_rcm, index &bwOldM, index &bwNewM, tLocalMatStruct::iterator full_mat_begin, index full_n_elem)
Partition a sub-graph into nParts and optionally apply RCM reordering within each part.
auto PartitionSerialAdj_Metis(tLocalMatStruct::const_iterator mat_begin, tLocalMatStruct::const_iterator mat_end, int nPart, index ind_offset=0, std::string metisType="KWAY", int metisNcuts=3, int metisUfactor=5, int metisSeed=0)
Partition a (sub-)graph using Metis.