/* File: omp_count_sort.c * * Purpose: Use count sort to sort a list of ints. * * Usage: ./omp_count_sort * n: number of elements in list * 'g': generate list using a random number generator * 'i': user input list * * Input: list (optional) * Output: sorted list * * Note: * 1. This version has no restrictions on the elements of the list * 2. DEBUG flag prints the contents of the list * 3. Changes to serial version: command line, Get_args, omp.h * parallel for, no use of memcpy */ #include #include #include #include "timer.h" #ifdef DEBUG const int RMAX = 100; #else const int RMAX = 10000000; #endif int thread_count; void Usage(char* prog_name); void Get_args(int argc, char* argv[], int* n_p, char* g_i_p); void Generate_list(int a[], int n); void Print_list(int a[], int n, char* title); void Read_list(int a[], int n); void Count_sort(int a[], int n); /*-----------------------------------------------------------------*/ int main(int argc, char* argv[]) { int n; char g_i; int* a; double start, finish; Get_args(argc, argv, &n, &g_i); a = malloc(n*sizeof(int)); if (g_i == 'g') { Generate_list(a, n); # ifdef DEBUG Print_list(a, n, "Before sort"); # endif } else { Read_list(a, n); } GET_TIME(start); Count_sort(a, n); GET_TIME(finish); # ifdef DEBUG Print_list(a, n, "After sort"); # endif printf("Elapsed time = %e seconds\n", finish - start); free(a); return 0; } /* main */ /*----------------------------------------------------------------- * Function: Usage * Purpose: Summary of how to run program */ void Usage(char* prog_name) { fprintf(stderr, "usage: %s \n", prog_name); fprintf(stderr, " n: number of elements in list\n"); fprintf(stderr, " 'g': generate list using a random number generator\n"); fprintf(stderr, " 'i': user input list\n"); } /* Usage */ /*----------------------------------------------------------------- * Function: Get_args * Purpose: Get and check command line arguments * In args: argc, argv * Out args: n_p, g_i_p */ void Get_args(int argc, char* argv[], int* n_p, char* g_i_p) { if (argc != 4 ) { Usage(argv[0]); exit(0); } thread_count = strtol(argv[1], NULL, 10); *n_p = strtol(argv[2], NULL, 10); *g_i_p = argv[3][0]; if (*n_p <= 0 || (*g_i_p != 'g' && *g_i_p != 'i') ) { Usage(argv[0]); exit(0); } } /* Get_args */ /*----------------------------------------------------------------- * Function: Generate_list * Purpose: Use random number generator to generate list elements * In args: n * Out args: a */ void Generate_list(int a[], int n) { int i; srandom(1); for (i = 0; i < n; i++) a[i] = random() % RMAX; } /* Generate_list */ /*----------------------------------------------------------------- * Function: Print_list * Purpose: Print the elements in the list * In args: a, n */ void Print_list(int a[], int n, char* title) { int i; printf("%s:\n", title); for (i = 0; i < n; i++) printf("%d ", a[i]); printf("\n\n"); } /* Print_list */ /*----------------------------------------------------------------- * Function: Read_list * Purpose: Read elements of list from stdin * In args: n * Out args: a */ void Read_list(int a[], int n) { int i; printf("Please enter the elements of the list\n"); for (i = 0; i < n; i++) scanf("%d", &a[i]); } /* Read_list */ /*----------------------------------------------------------------- * Function: Count_sort * Purpose: Sort list using enumeration sort * In args: n * In/out args: a */ void Count_sort(int a[], int n) { int i, j, count; int* temp = malloc(n*sizeof(int)); # pragma omp parallel num_threads(thread_count) default(none) \ private(i,j,count) shared(a, temp, n) { # ifdef DEBUG int my_rank = omp_get_thread_num(); int t = omp_get_num_threads(); # endif # pragma omp for for (i = 0; i < n; i++) { # ifdef DEBUG printf("Thread %d > i = %d, tc = %d\n", my_rank, i, t); # endif count = 0; for (j = 0; j < n; j++) if (a[j] < a[i]) count++; else if (a[j] == a[i] && j < i) count++; temp[count] = a[i]; } count = 0; # pragma omp for for (i = 0; i < n; i++) a[i] = temp[i]; } /* # pragma omp parallel */ free(temp); } /* Count_sort */