コード例 #1
0
void truncated_radix_sort(unsigned long int *morton_codes,
			  unsigned long int *sorted_morton_codes,
			  unsigned int *permutation_vector,
			  unsigned int *index,
			  unsigned int *level_record,
			  int N,
			  int population_threshold,
			  int sft, int lv){

  int BinSizes[MAXBINS] = {0};
  int BinCursor[MAXBINS] = {0};
  unsigned int *tmp_ptr;
  unsigned long int *tmp_code;


  if(N<=0){

    return;
  }
  else if(N<=population_threshold || sft < 0) { // Base case. The node is a leaf

    level_record[0] = lv; // record the level of the node
    memcpy(permutation_vector, index, N*sizeof(unsigned int)); // Copy the pernutation vector
    memcpy(sorted_morton_codes, morton_codes, N*sizeof(unsigned long int)); // Copy the Morton codes

    return;
  }
  else{

    int i, j;
    level_record[0] = lv;
    // Find which child each point belongs to
    for(j=0; j<N; j++){
      unsigned int ii = (morton_codes[j]>>sft) & 0x07;
      BinSizes[ii]++;
    }

    // scan prefix (must change this code)
    int offset = 0;
    for(i=0; i<MAXBINS; i++){
      int ss = BinSizes[i];
      BinCursor[i] = offset;
      offset += ss;
      BinSizes[i] = offset;
    }

    for(j=0; j<N; j++){
      unsigned int ii = (morton_codes[j]>>sft) & 0x07;
      permutation_vector[BinCursor[ii]] = index[j];
      sorted_morton_codes[BinCursor[ii]] = morton_codes[j];
      BinCursor[ii]++;
    }

    //swap the index pointers
    swap(&index, &permutation_vector);

    //swap the code pointers
    swap_long(&morton_codes, &sorted_morton_codes);

    /* Call the function recursively to split the lower levels */
#ifdef CILK
  cilk_for(i=0; i<MAXBINS; i++) {
#else
  for(i=0; i<MAXBINS; i++) {
#endif
      int offset = (i>0) ? BinSizes[i-1] : 0;
      int size = BinSizes[i] - offset;

      truncated_radix_sort(&morton_codes[offset],
			   &sorted_morton_codes[offset],
			   &permutation_vector[offset],
			   &index[offset], &level_record[offset],
			   size,
			   population_threshold,
			   sft-3, lv+1);
    }
  }
}
コード例 #2
0
ファイル: test_octree.c プロジェクト: mentekid/octree
int main(int argc, char** argv){

    // Time counting variables
    struct timeval startwtime, endwtime;
    double hashAvg=0, mortonAvg=0, sortingAvg=0, rearrangeAvg=0;
    extern int num_threads;


    if (argc != 7) { // Check if the command line arguments are correct
        printf("Usage: %s N dist pop rep L numThreads\n where\n N:number of points\n dist: distribution code (0-cube, 1-Plummer)\n pop: population threshold\n rep: repetitions\n L: maximum tree height.\n numThreads: number of threads to run this code with\n", argv[0]);
        return (1);
    }

    // Input command line arguments
    int N = atoi(argv[1]); // Number of points
    int dist = atoi(argv[2]); // Distribution identifier
    int population_threshold = atoi(argv[3]); // populatiton threshold
    int repeat = atoi(argv[4]); // number of independent runs
    int maxlev = atoi(argv[5]); // maximum tree height
    num_threads = atoi(argv[6]); //number of threads

    printf("Running for %d particles with maximum height: %d\n", N, maxlev);

    float *X = (float *) malloc(N*DIM*sizeof(float));
    float *Y = (float *) malloc(N*DIM*sizeof(float));

    unsigned int *hash_codes = (unsigned int *) malloc(DIM*N*sizeof(unsigned int));
    unsigned long int *morton_codes = (unsigned long int *) malloc(N*sizeof(unsigned long int));
    unsigned long int *sorted_morton_codes = (unsigned long int *) malloc(N*sizeof(unsigned long int));
    unsigned int *permutation_vector = (unsigned int *) malloc(N*sizeof(unsigned int));
    unsigned int *index = (unsigned int *) malloc(N*sizeof(unsigned int));
    unsigned int *level_record = (unsigned int *) calloc(N,sizeof(unsigned int)); // record of the leaf of the tree and their level

    // initialize the index
    int i = 0;
    for(i=0; i<N; i++){
        index[i] = i;
    }

    /* Generate a 3-dimensional data distribution */
    create_dataset(X, N, dist);

    /* Find the boundaries of the space */
    float max[DIM], min[DIM];
    find_max(max, X, N);
    find_min(min, X, N);

    int nbins = (1 << maxlev); // maximum number of boxes at the leaf level

    int it = 0;
    // Independent runs
    for(it = 0; it<repeat; it++){

        gettimeofday (&startwtime, NULL);

        compute_hash_codes(hash_codes, X, N, nbins, min, max); // compute the hash codes

        gettimeofday (&endwtime, NULL);

        double hash_time = (double)((endwtime.tv_usec - startwtime.tv_usec)
                /1.0e6 + endwtime.tv_sec - startwtime.tv_sec);
        hashAvg+=hash_time;

        printf("Time to compute the hash codes: %f\n", hash_time);


        gettimeofday (&startwtime, NULL);

        morton_encoding(morton_codes, hash_codes, N, maxlev); // computes the Morton codes of the particles

        gettimeofday (&endwtime, NULL);


        double morton_encoding_time = (double)((endwtime.tv_usec - startwtime.tv_usec)
                /1.0e6 + endwtime.tv_sec - startwtime.tv_sec);
        mortonAvg+=morton_encoding_time;

        printf("Time to compute the morton encoding: %f\n", morton_encoding_time);


        gettimeofday (&startwtime, NULL);

        // Truncated msd radix sort
        truncated_radix_sort(morton_codes, sorted_morton_codes,
                permutation_vector,
                index, level_record, N,
                population_threshold, 3*(maxlev-1), 0, num_threads);

        gettimeofday (&endwtime, NULL);


        double sort_time = (double)((endwtime.tv_usec - startwtime.tv_usec)
                /1.0e6 + endwtime.tv_sec - startwtime.tv_sec);
        sortingAvg+=sort_time;
        printf("Time for the truncated radix sort: %f\n", sort_time);

        gettimeofday (&startwtime, NULL);

        // Data rearrangement
        data_rearrangement(Y, X, permutation_vector, N);

        gettimeofday (&endwtime, NULL);


        double rearrange_time = (double)((endwtime.tv_usec - startwtime.tv_usec)
                /1.0e6 + endwtime.tv_sec - startwtime.tv_sec);
        rearrangeAvg+=rearrange_time;

        printf("Time to rearrange the particles in memory: %f\n", rearrange_time);

        /* The following code is for verification */
        // Check if every point is assigned to one leaf of the tree
        int pass = check_index(permutation_vector, N);
        printf("%d of %d on INDEX TEST\n", pass, N);
        /*
        if(pass){
            printf("Index test PASS\n");
        }
        else{
            printf("Index test FAIL\n");
        }
*/
        // Check is all particles that are in the same box have the same encoding.
        pass = check_codes(Y, sorted_morton_codes,
                level_record, N, maxlev);
        printf("%d of %d on ENCODING TEST\n", pass, N);
        /*
        if(pass){
            printf("Encoding test PASS\n");
        }
        else{
            printf("Encoding test FAIL\n");
        }
*/
    }
//compute and print average time for each stage
    hashAvg=hashAvg/repeat;
    printf("Average time for hashing: %f\n", hashAvg);

    mortonAvg=mortonAvg/repeat;
    printf("Average time for encoding: %f\n", mortonAvg);

    sortingAvg=sortingAvg/repeat;
    printf("Average time for sorting: %f\n", sortingAvg);

    rearrangeAvg=rearrangeAvg/repeat;
    printf("Average time for rearranging: %f\n", rearrangeAvg);

    /* clear memory */
    free(X);
    free(Y);
    free(hash_codes);
    free(morton_codes);
    free(sorted_morton_codes);
    free(permutation_vector);
    free(index);
    free(level_record);
}