#include #include #include #include "listrank.h" #include "alg_random.h" typedef struct master_d { LISTRANK_TYPE prefix; LDATA succ; LDATA index; } master_t; LDATA list_ranking(LDATA n, int k, list_t *List, THREADED) { register LDATA i, j, s, target, current, prev; register LISTRANK_TYPE val; LDATA block, start, finish, group, group_log, group_m1, times, shift, div, rem, master_tail, result, v, *succ_ptr, succ, seed,error, *Sums,tot,initial; master_t *Master; LDATA *Succ; master_t *s_master_ptr; list_t *list_ptr, *s_list_ptr, *f_list_ptr; LDATA list_head_ptr; s = k * THREADS; list_head_ptr = -1; Sums = (LDATA *) node_malloc((THREADS)*sizeof(LDATA), TH); Master = (master_t *) node_malloc((s+1)*sizeof(master_t),TH); Succ = (LDATA *) node_malloc(n*sizeof(LDATA),TH); node_Barrier(); /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ /* FIND THE HEAD */ block = n/THREADS; start = block * MYTHREAD; finish = start + block; if (MYTHREAD == THREADS-1) finish = n; tot = 0; for (i=start ; i> shift)) & group_m1) + (start += group); (++s_master_ptr) -> index = target; s_master_ptr -> succ = List[target].succ; List[target].succ = --current; for (j=1;j>= group_log) & group_m1) + (start += group); (++s_master_ptr) -> index = target; s_master_ptr -> succ = List[target].succ; List[target].succ = --current; } } v = rrandom_th(TH); v = (v >> shift); for (i=0;i>= group_log) & group_m1) + (start += group); (++s_master_ptr) -> index = target; s_master_ptr -> succ = List[target].succ; List[target].succ = --current; } node_Barrier(); on_one { tot = 0; for (i=0 ; i succ = initial = -List[list_head_ptr].succ; Master -> prefix = Master[initial].prefix = LISTRANK_IDENTITY; } else { initial = 0; Master -> prefix = LISTRANK_IDENTITY; Master -> index = list_head_ptr; Master -> succ = List[list_head_ptr].succ; List[list_head_ptr].succ = 0; } } node_Barrier(); /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ /* TRAVERSE THE SUBLISTS */ start = (k * MYTHREAD) + 1; finish = start + k; if ((MYTHREAD == 0) && (initial == 0)) start = 0; for (i = start; i < finish; i++) { current = Master[i].index; val = List[current].prefix; current = Master[i].succ; if (current >= 0) { /* We aren't at the end of the list */ target = List[current].succ; while (target >= 0) { val = List[current].prefix = (val LISTRANK_OPERATOR List[current].prefix); List[current].succ = - i; current = target; target = List[current].succ; } if (target > (- s - 1)) { /* We are at a new sublist */ Master[- target].prefix = val; Master[i].succ = -target; } else { /* We are at the end of the list */ List[current].prefix = (val LISTRANK_OPERATOR List[current].prefix); List[current].succ = - i; } } } node_Barrier(); /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ /* RANK THE MASTERS: */ on_one { succ = Master -> succ; current = 0; for (i=0 ; iprefix = s_list_ptr->prefix LISTRANK_OPERATOR Master[-s_list_ptr->succ].prefix; s_list_ptr -> succ = *(++succ_ptr); } node_free(Sums, TH); node_free(Master, TH); node_free(Succ, TH); return(node_Bcast_i(list_head_ptr,TH)); }