/* * Serial quicksort */ void serial_quicksort(int* array, int begin, int end){ int index = permut(array, begin, end); if(begin < index - 1) serial_quicksort(array,begin, index - 1); if(end > index + 1) serial_quicksort(array,index+1, end); }
void serial_quicksort(double *a,int left, int right) { if(left<right) { // Get lists of bigger and smaller items and final position of pivot // int pivotNewIndex = partition(a,left,right,choose_pivot(a,left,(left+right)/2,right)); int pivotNewIndex = partition(a,left,right,(left+right)/2); // Recursively sort elements smaller than the pivot serial_quicksort(a,left,pivotNewIndex-1); // Recursively sort elements at least as big as the pivot serial_quicksort(a,pivotNewIndex+1,right); } }
int main (int argc, char *argv[]) { int wrank, nproc, size, i, level = 0, local_size; double *array, *local_array, *local_left, *local_right, median; MPI_Init(&argc, &argv); /* initialize mpi */ MPI_Comm_size(MPI_COMM_WORLD, &nproc); /* get the number of processors */ MPI_Comm_rank(MPI_COMM_WORLD, &wrank); /* Get my number */ if(argc < 2 && wrank == 0) { printf(wrank == 0 ? "Usage: mpirun -np 4 ./qsort n (where n is the array size)\n" : ""); MPI_Finalize(); return -1; } size = atoi(argv[1]); // allocate whole array if on proc 0 if (wrank == 0) { array = (double *)calloc(size,sizeof(double)); fill_array(array,size); } // allocate local array for each processor local_size = size/nproc; local_array = (double*)calloc(local_size,sizeof(double)); int ttime=timer(); MPI_Scatter(array, local_size, MPI_DOUBLE, local_array, local_size, MPI_DOUBLE, 0, MPI_COMM_WORLD); serial_quicksort(local_array,0,local_size-1); paral_quicksort(0, nproc, MPI_COMM_WORLD, local_array, local_size, array); if(wrank == 0) { ttime=timer()-ttime; printf("procs: %d, Time: %f\n",nproc,ttime/1000000.0); // printf ("\n"); printf(is_sorted(array,size) ? "Success!!!\n" : "Fail!!!\n"); print_array(array,size); } if (wrank == 0) free(array); MPI_Finalize(); return 0; }
/* * The recursive quicksort */ void* quicksort(void* arg){ qsort_arg* qarg = (qsort_arg*)arg; int has_spawned = 0; pthread_t thread; if(qarg->step >= nb_steps) { //last step, each process sorts its part serially serial_quicksort(data, qarg->begin, qarg->end); } else { /*splits the data in two sets according to the pivot and spawns a new thread to sort one of the set */ qsort_arg* q_arg; int index = permut(data, qarg->begin, qarg->end); if(qarg->end > index + 1){ q_arg = malloc(sizeof(qsort_arg)); q_arg->step = qarg->step+1; q_arg->begin = index + 1; q_arg->end = qarg->end; if(pthread_create(&thread, NULL, quicksort,(void*)q_arg)) perror("Pthread_create"); else{ has_spawned = 1; } } if(qarg->begin < index - 1){ qarg->step++; qarg->end = index - 1; quicksort((void*)qarg); } } if(has_spawned) pthread_join(thread,NULL); return; }