29#include <unordered_map>
93 return _Adj[i].size();
108 if (mask[
root] == -1)
115 bool continueLoop =
true;
118 while(continueLoop && iter <
_N)
121 size_t currentDist = 0;
123 deque<int> currentVertices(1,
root);
125 while(currentVertices.size() > 0)
128 const int current = currentVertices.front();
142 currentVertices.pop_front();
143 currentDist = level[current] + 1;
144 for(
const auto &next :
_Adj[current])
146 if (level[next] == -1)
148 level[next] = currentDist;
149 currentVertices.push_back(next);
154 if(maxLevel < level[
root])
156 maxLevel = level[
root];
159 continueLoop =
false;
181 inline void addEdge(
const int &a,
const int &b)
183 _Adj[a].push_back(b);
192 size_t lowerBound = 0;
193 size_t nextIndex = 0;
195 while (nextIndex <
_N)
201 order[
root] = nextIndex++;
202 size_t currentDist = 0;
203 deque<int> currentVertices(1,
root);
204 while(currentVertices.size() > 0)
206 const int current = currentVertices.front();
207 currentVertices.pop_front();
208 currentDist = dist[current] + 1;
209 multiset<pair<int, int>> nextVertices;
210 for (
const auto &next :
_Adj[current])
212 if (dist[next] == -1)
214 dist[next] = currentDist;
215 nextVertices.insert(make_pair(
degree(next), next));
218 for(
const auto &next : nextVertices)
220 order[next.second] = nextIndex++;
221 currentVertices.push_back(next.second);
231 int newMaxBandwidth = 0;
232 long long int newSumBandwidth = 0;
233 int oldMaxBandwidth = 0;
234 long long int oldSumBandwidth = 0;
235 Vint iperm(perm.size());
236 for (
size_t i = 0; i < perm.size(); ++i)
240 for (
size_t i = 0; i <
_N; ++i)
242 for (
const auto &j :
_Adj[i])
244 const int newBandwidth = abs(perm[i] - perm[j]);
245 newMaxBandwidth =
max(newMaxBandwidth, newBandwidth);
246 newSumBandwidth += newBandwidth;
247 const int oldBandwidth = abs(((
int)i) - j);
248 oldMaxBandwidth =
max(oldMaxBandwidth, oldBandwidth);
249 oldSumBandwidth += oldBandwidth;
254 cout <<
"n:" <<
_N <<
" Old/New Max: " << ((double)oldMaxBandwidth)<<
"/"<<((
double)newMaxBandwidth);
255 cout <<
" Sum: " << ((double)oldSumBandwidth)<<
"/"<<((
double)newSumBandwidth) << endl;
261 outfile.open(
"spy_matrices.m");
263 outfile <<
" A = sparse(" <<
_N <<
"," <<
_N <<
"); \n";
264 outfile <<
" P = zeros(" <<
_N <<
",1); \n";
265 for (
size_t i = 0; i <
_N; ++i)
267 outfile <<
"P(" << perm[i] + 1 <<
")=" << i + 1 <<
"; \n";
269 for (
size_t i = 0; i <
_N; ++i)
271 for (
const auto &j :
_Adj[i])
273 outfile <<
"A(" << i + 1 <<
"," << j + 1 <<
") = 1; \n";
283 for (
const auto &i : v)
285 if (i < 0 || ((
size_t)i) > v.size())
296 return sum == v.size();
298void splitPerDomain(
int nel,
int nodesPerElt,
size_t nspmd,
int *domain,
int lda,
int offset,
int *elt2Nodes,
304 for (
int i = 0; i < nel; i++)
306 const int p = domain[i];
309 for (
int j = 0; j < nodesPerElt; j++)
311 nodes[p].addGlobalId(elt2Nodes[i * lda + j + offset]);
318 void cpp_reorder_elements(
int *NEL,
int *NSPMD,
int *NODES_PER_ELT,
int *OFFSET,
int *
LDA,
int *domain,
int *elt2Nodes,
int *permutation)
320 const int nel = *NEL;
321 const size_t nspmd = (size_t)*NSPMD;
322 const int nodesPerElt = *NODES_PER_ELT;
323 const int offset = *OFFSET;
324 const int lda = *
LDA;
329 vector<Adjacency> adjacencies(
nspmd);
330 vector<vector<Vint>> node2Elts(
nspmd);
331 vector<Vint> elt2LocalNodes(
nspmd);
333 splitPerDomain(nel, nodesPerElt,
nspmd, domain, lda, offset, elt2Nodes, nodesMapping, eltsParition);
335 for (
size_t p = 0; p <
nspmd; p++)
337 const int nb_local_elts = eltsParition.
globalId[p].size();
338 const int nb_local_nodes = nodesMapping[p].size();
339 node2Elts[p].resize(nb_local_nodes);
340 adjacencies[p].setNbVertices(nb_local_elts);
341 adjacencies[p].reserve(30);
342 elt2LocalNodes[p].resize(nb_local_elts * nodesPerElt);
347 for (
int i = 0; i < nel; i++)
349 const int p = domain[i];
351 const int e = eltsParition.
localId[i];
352 for (
int j = 0; j < nodesPerElt; j++)
355 const int local_node_id = nodesMapping[p].getCompactId(elt2Nodes[i * lda + j + offset]);
356 elt2LocalNodes[p][nodesPerElt * e + j] = local_node_id;
357 node2Elts[p][local_node_id].push_back(e);
362 for(
size_t p = 0; p <
nspmd; p++)
364 const size_t nel_local = eltsParition.
globalId[p].size();
365 Vint last(nel_local, -1);
366 for(
size_t e1 = 0 ; e1 < nel_local ; e1++)
368 for(
size_t j = 0 ; j < nodesPerElt ; j++)
370 const int n = elt2LocalNodes[p][nodesPerElt * e1 + j];
371 for(
auto & e2 : node2Elts[p][
n])
376 adjacencies[p].addEdge(e1, e2);
386 for (
size_t p = 0; p <
nspmd; ++p)
388 Vint index = adjacencies[p].CuthillMckee();
390 for (
size_t i = 0; i < index.size(); ++i)
393 permutation[(size_t)(start + index[i])] = 1 + eltsParition.
globalId[p][i];
395 start += index.size();
400 void CPP_REORDER_ELEMENTS_(
int *NEL,
int *NSPMD,
int *NODES_PER_ELT,
int *OFFSET,
int *
LDA,
int *domain,
int *elt2Nodes,
int *permutation)
404 void CPP_REORDER_ELEMENTS__(
int *NEL,
int *NSPMD,
int *NODES_PER_ELT,
int *OFFSET,
int *
LDA,
int *domain,
int *elt2Nodes,
int *permutation)
412 void cpp_reorder_elements_(
int *NEL,
int *NSPMD,
int *NODES_PER_ELT,
int *OFFSET,
int *
LDA,
int *domain,
int *elt2Nodes,
int *permutation)
416 void cpp_reorder_elements__(
int *NEL,
int *NSPMD,
int *NODES_PER_ELT,
int *OFFSET,
int *
LDA,
int *domain,
int *elt2Nodes,
int *permutation)
void printStats(const Vint &perm) const
size_t pickRoot(const Vint &mask, size_t &lower_bound) const
void setNbVertices(const size_t &s)
Vint CuthillMckee() const
void printPermutation(const vector< int > &perm) const
void reserve(const size_t &s)
void addEdge(const int &a, const int &b)
size_t degree(const size_t &i) const
int getCompactId(const int &i) const
int getGlobalId(const int &i) const
unordered_map< int, int > toCompact
void addGlobalId(const int &i)
bool is_permutation(const Vint &v)
void cpp_reorder_elements__(int *NEL, int *NSPMD, int *NODES_PER_ELT, int *OFFSET, int *LDA, int *domain, int *elt2Nodes, int *permutation)
void CPP_REORDER_ELEMENTS_(int *NEL, int *NSPMD, int *NODES_PER_ELT, int *OFFSET, int *LDA, int *domain, int *elt2Nodes, int *permutation)
void splitPerDomain(int nel, int nodesPerElt, size_t nspmd, int *domain, int lda, int offset, int *elt2Nodes, Vorder &nodes, ElementPartition &elts)
void _FCALL CPP_REORDER_ELEMENTS(int *NEL, int *NSPMD, int *NODES_PER_ELT, int *OFFSET, int *LDA, int *domain, int *elt2Nodes, int *permutation)
void CPP_REORDER_ELEMENTS__(int *NEL, int *NSPMD, int *NODES_PER_ELT, int *OFFSET, int *LDA, int *domain, int *elt2Nodes, int *permutation)
void cpp_reorder_elements_(int *NEL, int *NSPMD, int *NODES_PER_ELT, int *OFFSET, int *LDA, int *domain, int *elt2Nodes, int *permutation)
vector< NodeMapping > Vorder
void cpp_reorder_elements(int *NEL, int *NSPMD, int *NODES_PER_ELT, int *OFFSET, int *LDA, int *domain, int *elt2Nodes, int *permutation)