template <class type> void sort_suffixes(type p) { int lim = * max_element(p.begin(), p.end()), n = p.size(); for (int i = 0; i < n; i++) { P[0][i] = p[i]; } for (stp = 1; (1 << (stp - 1)) <= n; stp++) { int gap = 1 << (stp - 1); for (int i = 0; i < n; i++) { if (gap + i < n) A[i] = info(P[stp - 1][i], P[stp - 1][i + gap], i); else A[i] = info(P[stp - 1][i], -1, i); } sort_radix(n, lim); P[stp][A[0].id] = lim = 0; for (int i = 1; i < n; i++) { if (A[i].a == A[i - 1].a && A[i].b == A[i - 1].b) { P[stp][A[i].id] = lim; } else { P[stp][A[i].id] = ++lim; } } } sa = std::vector <int> (n, -1); for (int i = 0; i < n; i++) { sa[P[stp - 1][i]] = i; } }
slint_t mpi_select_sample_regular(elements_t *s, slint_t nparts, partcond_t *pconds, slint_t nsamples, splitter_t *sp, int size, int rank, MPI_Comm comm) /* sl_proto, sl_func mpi_select_sample_regular */ { slint_t i, j; slweight_t w, wi, wold; const slint_t nslocal = nsamples; const slint_t nsglobal = nslocal * size; const slint_t nsplitter = nparts - 1; #ifdef elem_weight slpwkey_t lskeys[nslocal]; slpwkey_t gskeys[nsglobal]; #else slkey_pure_t lskeys[nslocal]; slkey_pure_t gskeys[nsglobal]; #endif slkey_pure_t skeys[nsplitter]; slint_t lgcounts[2]; #ifdef elem_weight slweight_t lgweights[2]; #endif partcond_intern_t pci[nparts]; elements_t gs, e; #ifdef elem_weight slint_t doweights; #else # define doweights 0 #endif #ifdef elem_weight doweights = ((pconds->pcm & (SLPC_WEIGHTS_MM|SLPC_WEIGHTS_LH)) != 0); #endif #ifdef elem_weight if (doweights) mpi_elements_get_counts_and_weights(s, 1, lgcounts, lgweights, -1, size, rank, comm); else #endif mpi_elements_get_counts(s, &lgcounts[0], &lgcounts[1], -1, size, rank, comm); init_partconds_intern(nparts, pci, pconds, nparts, lgcounts[1], elem_weight_ifelse(doweights?lgweights[1]:0, 0)); SL_TRACE_IF(MSS_TRACE_IF, "counts: %" slint_fmt " / %" slint_fmt, lgcounts[0], lgcounts[1]); #ifdef elem_weight if (doweights) SL_TRACE_IF(MSS_TRACE_IF, "weights: %" slweight_fmt " / %" slweight_fmt "", lgweights[0], lgweights[1]); #endif #ifdef elem_weight j = 0; w = 0; wold = 0; for (i = 0; i < nslocal; ++i) { wi = (i + 1) * lgweights[0] / (nslocal + 1); while (w < wi && j < lgcounts[0]) { w += elem_weight(s, j); ++j; } if (j < lgcounts[0]) lskeys[i].pkey = *key_get_pure(elem_key_at(s, j)); else lskeys[i].pkey = *key_get_pure(elem_key_at(s, j - 1)) + 1; lskeys[i].weight = w - wold; wold = w; /* printf("%" slint_fmt ": key: %" slint_fmt " / weight: %" slweight_fmt "\n", i, lskeys[i].pkey, lskeys[i].weight);*/ } #else for (i = 0; i < nslocal; ++i) lskeys[i] = *key_get_pure(elem_key_at(s, sl_pivot_equal(s->size, i + 1, nslocal))); #endif #ifdef elem_weight MPI_Gather(lskeys, nslocal, pwkey_mpi_datatype, gskeys, nslocal, pwkey_mpi_datatype, MSS_ROOT, comm); #else MPI_Gather(lskeys, nslocal, pkey_mpi_datatype, gskeys, nslocal, pkey_mpi_datatype, MSS_ROOT, comm); #endif if (rank == MSS_ROOT) { elements_alloc(&gs, nsglobal, SLCM_ALL); gs.size = nsglobal; #ifdef elem_weight for (i = 0; i < nsglobal; ++i) { key_set_pure(elem_key_at(&gs, i), gskeys[i].pkey); elem_weight(&gs, i) = gskeys[i].weight; } #else for (i = 0; i < nsglobal; ++i) key_set_pure(elem_key_at(&gs, i), gskeys[i]); #endif sort_radix(&gs, NULL, -1, -1, -1); /* printf("samples:\n"); elements_print_all(&gs);*/ #ifdef elem_weight j = 0; w = 0; for (i = 0; i < nsplitter; ++i) { wi = (i + 1) * lgweights[1] / (nsplitter + 1); while (w < wi && j < nsglobal) { w += elem_weight(&gs, j); ++j; } if (j > 0 && (wi - w + elem_weight(&gs, j - 1)) <= (w - wi)) { w -= elem_weight(&gs, j - 1); --j; } skeys[i] = *key_get_pure(elem_key_at(&gs, j - 1)); /* printf("%" slint_fmt ": key: %" slint_fmt " / weight: %" slweight_fmt "\n", i, skeys[i], w);*/ } skeys[i] = *key_get_pure(elem_key_at(&gs, sl_pivot_equal(gs.size, i + 1, nsplitter))); #else for (i = 0; i < nsplitter; ++i) skeys[i] = *key_get_pure(elem_key_at(&gs, sl_pivot_equal(gs.size, i + 1, nsplitter))); #endif elements_free(&gs); } #ifdef elem_weight MPI_Bcast(&skeys, nsplitter, pwkey_mpi_datatype, MSS_ROOT, comm); #else MPI_Bcast(&skeys, nsplitter, pkey_mpi_datatype, MSS_ROOT, comm); #endif sp->displs[0] = 0; for (i = 0; i < nsplitter; ++i) { elem_assign_at(s, sp->displs[i], &e); e.size = s->size - sp->displs[i]; sp->displs[i + 1] = sp->displs[i] + sl_search_binary_lt(&e, &skeys[i]); printf("%d: %" slint_fmt ": %" sl_key_pure_type_fmt " -> displs[%" slint_fmt "] = %d\n", rank, i, skeys[i], i + 1, sp->displs[i + 1]); } return 0; }
static int test1(unsigned int ui_trials, unsigned int ui_arr_max_size) { int i_ret = -1; int i_min_data = 0; int i_max_data = 0; unsigned int ui_i = 0; unsigned int ui_k = 0; unsigned int ui_arr_size = 0; int *pi_arr_src = NULL; int *pi_arr_dst[2] = {NULL, NULL}; SORT_RET_E e_sort = eSORT_FAILURE; if((0 == ui_arr_max_size)|| (0 == ui_trials)) { i_ret = -1; goto LBL_TEST2; } for(ui_i = 0 ; ui_i < ui_trials ; ui_i++) { do { ui_arr_size = (unsigned int)rand() % (ui_arr_max_size + 1); }while(ui_arr_size <= 1); printf("Size of the array is %u iteration %u\n",ui_arr_size, ui_i); /*Allocate memory for the source array + arrays to be sorted with different algos*/ pi_arr_src = (int *)calloc(ui_arr_size * sizeof(int) , 3); if(NULL == pi_arr_src) { printf("Can't allocate memory for sorting all\n"); i_ret = -4; goto LBL_TEST2; } pi_arr_dst[0] = pi_arr_src + ui_arr_size; pi_arr_dst[1] = pi_arr_dst[0] + ui_arr_size; for(ui_k = 0 ; ui_k < ui_arr_size ; ui_k++) { pi_arr_src[ui_k] = (short)rand(); pi_arr_dst[0][ui_k] = pi_arr_src[ui_k]; pi_arr_dst[1][ui_k] = pi_arr_src[ui_k]; if((i_min_data > pi_arr_src[ui_k])|| (0 == ui_k)) { i_min_data = pi_arr_src[ui_k]; } if((i_max_data < pi_arr_src[ui_k])|| (0 == ui_k)) { i_max_data = pi_arr_src[ui_k]; } } printf("Source:\n"); for(ui_k = 0 ; ui_k < ui_arr_size ; ui_k++) { printf("%d%s", pi_arr_src[ui_k], (ui_k == (ui_arr_size - 1))?"\n":", "); } printf("Minimum value is :%d\n",i_min_data); printf("Maximum value is :%d\n",i_max_data); printf("Difference is :%d\n",(i_max_data - i_min_data)); e_sort = sort_counting(pi_arr_dst[0], ui_arr_size, i_min_data, i_max_data); if(eSORT_SUCCESS != e_sort) { printf("Iteration %u Counting Sort failed\n", ui_i); } printf("Counting Sort:\n"); for(ui_k = 0 ; ui_k < ui_arr_size ; ui_k++) { printf("%d%s", pi_arr_dst[0][ui_k], (ui_k == (ui_arr_size - 1))?"\n":", "); } e_sort = sort_radix(pi_arr_dst[1], ui_arr_size, 5, 10); if(eSORT_SUCCESS != e_sort) { printf("Iteration %u Radix Sort failed\n", ui_i); } printf("Radix Sort:\n"); for(ui_k = 0 ; ui_k < ui_arr_size ; ui_k++) { printf("%d%s", pi_arr_dst[1][ui_k], (ui_k == (ui_arr_size - 1))?"\n":", "); } printf("----------------------------------------\n"); if(NULL != pi_arr_src) { free(pi_arr_src); pi_arr_src = NULL; } } i_ret = 0; LBL_TEST2: if(NULL != pi_arr_src) { free(pi_arr_src); pi_arr_src = NULL; } return i_ret; }