void parallel_init(graph_t& g, unsigned threadnum, vector<vector<uint64_t> >& global_input_tasks) { global_input_tasks.resize(threadnum); for (uint64_t vid=0;vid<g.vertex_num();vid++) { g.csr_vertex_property(vid).root = vid; global_input_tasks[vertex_distributor(vid, threadnum)].push_back(vid); } }
void parallel_wcc(graph_t &g, unsigned threadnum, vector<vector<uint64_t> > &global_input_tasks, gBenchPerf_multi &perf, int perf_group) { vector<vector<uint64_t> > global_output_tasks(threadnum*threadnum); bool stop = false; #pragma omp parallel num_threads(threadnum) shared(stop,global_input_tasks,global_output_tasks,perf) { unsigned tid = omp_get_thread_num(); vector<uint64_t> & input_tasks = global_input_tasks[tid]; perf.open(tid, perf_group); perf.start(tid, perf_group); while(!stop) { #pragma omp barrier // process local queue stop = true; for (unsigned i=0;i<input_tasks.size();i++) { uint64_t vid=input_tasks[i]; uint64_t size, begin; size = g.csr_in_edges_size(vid); begin = g.csr_in_edges_begin(vid); for (uint64_t i=0;i<size;i++) { uint64_t dest_vid = g.csr_in_edge(begin,i); if(g.csr_vertex_property(dest_vid).root > g.csr_vertex_property(vid).root) { __sync_bool_compare_and_swap(&(g.csr_vertex_property(dest_vid).root), g.csr_vertex_property(dest_vid).root, g.csr_vertex_property(vid).root); global_output_tasks[vertex_distributor(dest_vid,threadnum)+tid*threadnum].push_back(dest_vid); } } size = g.csr_out_edges_size(vid); begin = g.csr_out_edges_begin(vid); for (uint64_t i=0;i<size;i++) { uint64_t dest_vid = g.csr_out_edge(begin,i); bool done = false; while(!done) { if(g.csr_vertex_property(dest_vid).root > g.csr_vertex_property(vid).root) { done = __sync_bool_compare_and_swap(&(g.csr_vertex_property(dest_vid).root), g.csr_vertex_property(dest_vid).root, g.csr_vertex_property(vid).root); if(done) { global_output_tasks[vertex_distributor(dest_vid,threadnum)+tid*threadnum].push_back(dest_vid); } } else { done = true; } } } } #pragma omp barrier input_tasks.clear(); for (unsigned i=0;i<threadnum;i++) { if (global_output_tasks[i*threadnum+tid].size()!=0) { stop = false; input_tasks.insert(input_tasks.end(), global_output_tasks[i*threadnum+tid].begin(), global_output_tasks[i*threadnum+tid].end()); global_output_tasks[i*threadnum+tid].clear(); } } #pragma omp barrier } perf.stop(tid, perf_group); } }