예제 #1
0
 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;
}
예제 #3
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;

}