59 static void greedy(
size_t NNodes,
const std::vector< std::vector<index_t> > &NNList, std::vector<char> &colour){
64 for(node=0;node<NNodes;node++){
65 if(NNList[node].size()>0){
72 for(;node<NNodes;node++){
73 if(NNList[node].size()==0)
76 std::vector<bool> used_colours(max_colour,
false);;
77 for(std::vector<index_t>::const_iterator it=NNList[node].begin();it!=NNList[node].end();++it){
79 if(colour[*it]>=max_colour){
81 used_colours.resize(max_colour,
false);
84 used_colours[colour[*it]] =
true;
102 static void GebremedhinManne(
size_t NNodes,
const std::vector< std::vector<index_t> > &NNList, std::vector<char> &colour){
104 int max_iterations = 128;
105 std::vector<bool> conflicts_exist(max_iterations,
false);;
106 std::vector<bool> conflict(NNodes);
108 #pragma omp parallel firstprivate(NNodes)
111 std::default_random_engine generator;
112 std::uniform_int_distribution<int> distribution(0,6);
115 for(
size_t i=0;i<NNodes;i++){
116 colour[i] = distribution(generator);
120 for(
int k=0;k<max_iterations;k++){
122 #pragma omp for schedule(guided)
123 for(
size_t i=0;i<NNodes;i++){
130 unsigned long colours = 0;
132 for(std::vector<index_t>::const_iterator it=NNList[i].begin();it!=NNList[i].end();++it){
134 colours = colours | 1<<c;
138 for(
size_t j=0;j<64;j++){
148 for(
size_t i=0;i<NNodes;i++){
149 for(std::vector<index_t>::const_iterator it=NNList[i].begin();it!=NNList[i].end();++it){
150 if(colour[i]==colour[*it] && i<(
size_t)*it){
152 conflicts_exist[k] =
true;
156 if(!conflicts_exist[k])
163 const std::vector< std::vector<index_t> > &NNList,
164 const std::vector< std::vector<index_t> > &send,
165 const std::vector< std::vector<index_t> > &recv,
166 const std::vector<int> &node_owner,
167 std::vector<char> &colour){
168 int max_iterations = 4096;
169 std::vector<int> conflicts_exist(max_iterations, 0);
170 std::vector<bool> conflict(NNodes);
173 MPI_Comm_rank(comm, &rank);
177 assert(NNodes==colour.size());
179 bool serialize=
false;
181 #pragma omp parallel firstprivate(NNodes)
184 std::default_random_engine generator;
185 std::uniform_int_distribution<int> distribution(0,K);
188 for(
size_t i=0;i<NNodes;i++){
189 colour[i] = distribution(generator);
195 halo_update<char, 1>(comm, send, recv, colour);
198 for(
int k=0;k<max_iterations;k++){
204 std::vector<char> colour_deck;
206 colour_deck.push_back(i);
207 std::random_shuffle(colour_deck.begin(), colour_deck.end());
210 #pragma omp for schedule(static)
211 for(
size_t i=0;i<NNodes;i++){
213 std::random_shuffle(colour_deck.begin(), colour_deck.end());
215 if(!conflict[i] || node_owner[i]!=rank)
222 unsigned long colours = 0;
223 for(std::vector<index_t>::const_iterator it=NNList[i].begin();it!=NNList[i].end();++it){
225 colours = colours | 1<<c;
230 for(std::vector<char>::const_iterator it=colour_deck.begin();it!=colour_deck.end();++it){
231 if(colours&(1<<*it)){
238 for(
size_t j=K;j<64;j++){
248 halo_update<char, 1>(comm, send, recv, colour);
252 #pragma omp for schedule(static)
254 if(node_owner[i]!=rank)
257 for(std::vector<index_t>::const_iterator it=NNList[i].begin();it!=NNList[i].end();++it){
258 if(colour[i]==colour[*it] && i<*it){
260 conflicts_exist[k]++;
268 MPI_Allreduce(MPI_IN_PLACE, &(conflicts_exist[k]), 1, MPI_INT, MPI_SUM, comm);
271 if(k>=K && conflicts_exist[k-K]==conflicts_exist[k]){
273 conflicts_exist[i] = -1;
278 if(conflicts_exist[k]==0)
286 MPI_Comm_size(comm, &nranks);
288 halo_update<char, 1>(comm, send, recv, colour);
290 for(
int i=0;i<nranks;i++)
291 repair(NNodes, NNList, colour);
301 static void repair(
size_t NNodes,
const std::vector< std::vector<index_t> > &NNList, std::vector<char> &colour){
303 std::vector<size_t> conflicts;
304 #pragma omp for schedule(static, 64)
305 for(
size_t i=0;i<NNodes;i++){
307 for(std::vector<index_t>::const_iterator it=NNList[i].begin();it!=NNList[i].end();++it){
308 char k = colour[*it];
310 conflicts.push_back(i);
319 for(
int i=0;i<nthreads;i++){
321 for(std::vector<size_t>::const_iterator it=conflicts.begin();it!=conflicts.end();++it){
322 unsigned long colours = 0;
323 for(std::vector<index_t>::const_iterator jt=NNList[*it].begin();jt!=NNList[*it].end();++jt){
324 colours = colours | 1<<(colour[*jt]);
328 for(
size_t j=0;j<64;j++){
340 static void repair(
size_t NNodes, std::vector< std::vector<index_t> > &NNList, std::vector< std::set<index_t> > &marked_edges, std::vector<char> &colour){
342 std::vector<size_t> conflicts;
343 #pragma omp for schedule(static, 64)
344 for(
size_t i=0;i<NNodes;i++){
345 if(marked_edges[i].empty())
349 for(std::vector<index_t>::const_iterator it=NNList[i].begin();it!=NNList[i].end();++it){
350 char k = colour[*it];
352 conflicts.push_back(i);
361 for(
int i=0;i<nthreads;i++){
363 for(std::vector<size_t>::const_iterator it=conflicts.begin();it!=conflicts.end();++it){
364 unsigned long colours = 0;
365 for(std::vector<index_t>::const_iterator jt=NNList[*it].begin();jt!=NNList[*it].end();++jt){
366 colours = colours | 1<<(colour[*jt]);
370 for(
size_t j=0;j<64;j++){
382 static void RokosGorman(std::vector< std::vector<index_t>* > NNList,
size_t NNodes,
383 int node_colour[], std::vector< std::vector< std::vector<index_t> > >& ind_sets,
384 int max_colour,
size_t* worklist[],
size_t worklist_size[],
int tid){
385 #pragma omp single nowait
387 for(
int i=0; i<3; ++i)
388 worklist_size[i] = 0;
392 std::vector<index_t> forbiddenColours(max_colour, std::numeric_limits<index_t>::max());
395 #pragma omp for schedule(guided)
396 for(
size_t i=0; i<NNodes; ++i){
397 index_t n = *NNList[i]->begin();
398 for(
typename std::vector<index_t>::const_iterator it=NNList[i]->begin()+1; it!=NNList[i]->end(); ++it){
399 int c = node_colour[*it];
401 forbiddenColours[c] = n;
404 for(
size_t j=0; j<forbiddenColours.size(); ++j){
405 if(forbiddenColours[j] != n){
413 std::vector<size_t> conflicts;
415 #pragma omp for schedule(guided) nowait
416 for(
size_t i=0; i<NNodes; ++i){
417 bool defective =
false;
418 index_t n = *NNList[i]->begin();
419 for(
typename std::vector<index_t>::const_iterator it=NNList[i]->begin()+1; it!=NNList[i]->end(); ++it){
420 if(node_colour[n] == node_colour[*it]){
431 conflicts.push_back(i);
433 for(
typename std::vector<index_t>::const_iterator it=NNList[i]->begin()+1; it!=NNList[i]->end(); ++it){
434 int c = node_colour[*it];
435 forbiddenColours[c] = n;
438 for(
size_t j=0; j<forbiddenColours.size(); j++){
439 if(forbiddenColours[j] != n){
445 ind_sets[tid][node_colour[n]].push_back(n);
452 memcpy(&worklist[0][pos], &conflicts[0], conflicts.size() *
sizeof(size_t));
460 while(worklist_size[wl]){
461 #pragma omp for schedule(guided) nowait
462 for(
size_t item=0; item<worklist_size[wl]; ++item){
463 size_t i = worklist[wl][item];
464 bool defective =
false;
465 index_t n = *NNList[i]->begin();
466 for(
typename std::vector<index_t>::const_iterator it=NNList[i]->begin()+1; it!=NNList[i]->end(); ++it){
467 if(node_colour[n] == node_colour[*it]){
478 conflicts.push_back(i);
480 for(
typename std::vector<index_t>::const_iterator it=NNList[i]->begin()+1; it!=NNList[i]->end(); ++it){
481 int c = node_colour[*it];
482 forbiddenColours[c] = n;
485 for(
size_t j=0; j<forbiddenColours.size(); j++){
486 if(forbiddenColours[j] != n){
492 ind_sets[tid][node_colour[n]].push_back(n);
501 memcpy(&worklist[wl][pos], &conflicts[0], conflicts.size() *
sizeof(size_t));
508 worklist_size[(wl+1)%3] = 0;
static void GebremedhinManne(MPI_Comm comm, size_t NNodes, const std::vector< std::vector< index_t > > &NNList, const std::vector< std::vector< index_t > > &send, const std::vector< std::vector< index_t > > &recv, const std::vector< int > &node_owner, std::vector< char > &colour)
static void repair(size_t NNodes, const std::vector< std::vector< index_t > > &NNList, std::vector< char > &colour)
static void GebremedhinManne(size_t NNodes, const std::vector< std::vector< index_t > > &NNList, std::vector< char > &colour)
Performs a simple first breath greedy graph colouring of a local undirected graph.
static void greedy(size_t NNodes, const std::vector< std::vector< index_t > > &NNList, std::vector< char > &colour)
static void RokosGorman(std::vector< std::vector< index_t > * > NNList, size_t NNodes, int node_colour[], std::vector< std::vector< std::vector< index_t > > > &ind_sets, int max_colour, size_t *worklist[], size_t worklist_size[], int tid)
int pragmatic_thread_id()
static void repair(size_t NNodes, std::vector< std::vector< index_t > > &NNList, std::vector< std::set< index_t > > &marked_edges, std::vector< char > &colour)
size_t pragmatic_omp_atomic_capture(size_t *shared, size_t inc)