fork download
  1. // C program to implement the Quick Sort
  2. // Algorithm using MPI
  3. #include <mpi.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <time.h>
  7. #include <unistd.h>
  8. using namespace std;
  9.  
  10. // Function to swap two numbers
  11. void swap(int* arr, int i, int j)
  12. {
  13. int t = arr[i];
  14. arr[i] = arr[j];
  15. arr[j] = t;
  16. }
  17.  
  18. // Function that performs the Quick Sort
  19. // for an array arr[] starting from the
  20. // index start and ending at index end
  21. void quicksort(int* arr, int start, int end)
  22. {
  23. int pivot, index;
  24.  
  25. // Base Case
  26. if (end <= 1)
  27. return;
  28.  
  29. // Pick pivot and swap with first
  30. // element Pivot is middle element
  31. pivot = arr[start + end / 2];
  32. swap(arr, start, start + end / 2);
  33.  
  34. // Partitioning Steps
  35. index = start;
  36.  
  37. // Iterate over the range [start, end]
  38. for (int i = start + 1; i < start + end; i++) {
  39.  
  40. // Swap if the element is less
  41. // than the pivot element
  42. if (arr[i] < pivot) {
  43. index++;
  44. swap(arr, i, index);
  45. }
  46. }
  47.  
  48. // Swap the pivot into place
  49. swap(arr, start, index);
  50.  
  51. // Recursive Call for sorting
  52. // of quick sort function
  53. quicksort(arr, start, index - start);
  54. quicksort(arr, index + 1, start + end - index - 1);
  55. }
  56.  
  57. // Function that merges the two arrays
  58. int* merge(int* arr1, int n1, int* arr2, int n2)
  59. {
  60. int* result = (int*)malloc((n1 + n2) * sizeof(int));
  61. int i = 0;
  62. int j = 0;
  63. int k;
  64.  
  65. for (k = 0; k < n1 + n2; k++) {
  66. if (i >= n1) {
  67. result[k] = arr2[j];
  68. j++;
  69. }
  70. else if (j >= n2) {
  71. result[k] = arr1[i];
  72. i++;
  73. }
  74.  
  75. // Indices in bounds as i < n1
  76. // && j < n2
  77. else if (arr1[i] < arr2[j]) {
  78. result[k] = arr1[i];
  79. i++;
  80. }
  81.  
  82. // v2[j] <= v1[i]
  83. else {
  84. result[k] = arr2[j];
  85. j++;
  86. }
  87. }
  88. return result;
  89. }
  90.  
  91. // Driver Code
  92. int main(int argc, char* argv[])
  93. {
  94. int number_of_elements;
  95. int* data = NULL;
  96. int chunk_size, own_chunk_size;
  97. int* chunk;
  98. FILE* file = NULL;
  99. double time_taken;
  100. MPI_Status status;
  101.  
  102. if (argc != 3) {
  103. printf("Desired number of arguments are not their "
  104. "in argv....\n");
  105. printf("2 files required first one input and "
  106. "second one output....\n");
  107. exit(-1);
  108. }
  109.  
  110. int number_of_process, rank_of_process;
  111. int rc = MPI_Init(&argc, &argv);
  112.  
  113. if (rc != MPI_SUCCESS) {
  114. printf("Error in creating MPI "
  115. "program.\n "
  116. "Terminating......\n");
  117. MPI_Abort(MPI_COMM_WORLD, rc);
  118. }
  119.  
  120. MPI_Comm_size(MPI_COMM_WORLD, &number_of_process);
  121. MPI_Comm_rank(MPI_COMM_WORLD, &rank_of_process);
  122.  
  123. if (rank_of_process == 0) {
  124. // Opening the file
  125. file = fopen(argv[1], "r");
  126.  
  127. // Printing Error message if any
  128. if (file == NULL) {
  129. printf("Error in opening file\n");
  130. exit(-1);
  131. }
  132.  
  133. // Reading number of Elements in file ...
  134. // First Value in file is number of Elements
  135. "Reading number of Elements From file ....\n");
  136. fscanf(file, "%d", &number_of_elements);
  137. printf("Number of Elements in the file is %d \n",
  138. number_of_elements);
  139.  
  140. // Computing chunk size
  141. chunk_size
  142. = (number_of_elements % number_of_process == 0)
  143. ? (number_of_elements / number_of_process)
  144. : (number_of_elements / number_of_process
  145. - 1);
  146.  
  147. data = (int*)malloc(number_of_process * chunk_size
  148. * sizeof(int));
  149.  
  150. // Reading the rest elements in which
  151. // operation is being performed
  152. printf("Reading the array from the file.......\n");
  153. for (int i = 0; i < number_of_elements; i++) {
  154. fscanf(file, "%d", &data[i]);
  155. }
  156.  
  157. // Padding data with zero
  158. for (int i = number_of_elements;
  159. i < number_of_process * chunk_size; i++) {
  160. data[i] = 0;
  161. }
  162.  
  163. // Printing the array read from file
  164. printf("Elements in the array is : \n");
  165. for (int i = 0; i < number_of_elements; i++) {
  166. printf("%d ", data[i]);
  167. }
  168.  
  169. printf("\n");
  170.  
  171. fclose(file);
  172. file = NULL;
  173. }
  174.  
  175. // Blocks all process until reach this point
  176. MPI_Barrier(MPI_COMM_WORLD);
  177.  
  178. // Starts Timer
  179. time_taken -= MPI_Wtime();
  180.  
  181. // BroadCast the Size to all the
  182. // process from root process
  183. MPI_Bcast(&number_of_elements, 1, MPI_INT, 0,
  184. MPI_COMM_WORLD);
  185.  
  186. // Computing chunk size
  187. chunk_size
  188. = (number_of_elements % number_of_process == 0)
  189. ? (number_of_elements / number_of_process)
  190. : number_of_elements
  191. / (number_of_process - 1);
  192.  
  193. // Calculating total size of chunk
  194. // according to bits
  195. chunk = (int*)malloc(chunk_size * sizeof(int));
  196.  
  197. // Scatter the chuck size data to all process
  198. MPI_Scatter(data, chunk_size, MPI_INT, chunk,
  199. chunk_size, MPI_INT, 0, MPI_COMM_WORLD);
  200. free(data);
  201. data = NULL;
  202.  
  203. // Compute size of own chunk and
  204. // then sort them
  205. // using quick sort
  206.  
  207. own_chunk_size = (number_of_elements
  208. >= chunk_size * (rank_of_process + 1))
  209. ? chunk_size
  210. : (number_of_elements
  211. - chunk_size * rank_of_process);
  212.  
  213. // Sorting array with quick sort for every
  214. // chunk as called by process
  215. quicksort(chunk, 0, own_chunk_size);
  216.  
  217. for (int step = 1; step < number_of_process;
  218. step = 2 * step) {
  219. if (rank_of_process % (2 * step) != 0) {
  220. MPI_Send(chunk, own_chunk_size, MPI_INT,
  221. rank_of_process - step, 0,
  222. MPI_COMM_WORLD);
  223. break;
  224. }
  225.  
  226. if (rank_of_process + step < number_of_process) {
  227. int received_chunk_size
  228. = (number_of_elements
  229. >= chunk_size
  230. * (rank_of_process + 2 * step))
  231. ? (chunk_size * step)
  232. : (number_of_elements
  233. - chunk_size
  234. * (rank_of_process + step));
  235. int* chunk_received;
  236. chunk_received = (int*)malloc(
  237. received_chunk_size * sizeof(int));
  238. MPI_Recv(chunk_received, received_chunk_size,
  239. MPI_INT, rank_of_process + step, 0,
  240. MPI_COMM_WORLD, &status);
  241.  
  242. data = merge(chunk, own_chunk_size,
  243. chunk_received,
  244. received_chunk_size);
  245.  
  246. free(chunk);
  247. free(chunk_received);
  248. chunk = data;
  249. own_chunk_size
  250. = own_chunk_size + received_chunk_size;
  251. }
  252. }
  253.  
  254. // Stop the timer
  255. time_taken += MPI_Wtime();
  256.  
  257. // Opening the other file as taken form input
  258. // and writing it to the file and giving it
  259. // as the output
  260. if (rank_of_process == 0) {
  261. // Opening the file
  262. file = fopen(argv[2], "w");
  263.  
  264. if (file == NULL) {
  265. printf("Error in opening file... \n");
  266. exit(-1);
  267. }
  268.  
  269. // Printing total number of elements
  270. // in the file
  271. file,
  272. "Total number of Elements in the array : %d\n",
  273. own_chunk_size);
  274.  
  275. // Printing the value of array in the file
  276. for (int i = 0; i < own_chunk_size; i++) {
  277. fprintf(file, "%d ", chunk[i]);
  278. }
  279.  
  280. // Closing the file
  281. fclose(file);
  282.  
  283. printf("\n\n\n\nResult printed in output.txt file "
  284. "and shown below: \n");
  285.  
  286. // For Printing in the terminal
  287. printf("Total number of Elements given as input : "
  288. "%d\n",
  289. number_of_elements);
  290. printf("Sorted array is: \n");
  291.  
  292. for (int i = 0; i < number_of_elements; i++) {
  293. printf("%d ", chunk[i]);
  294. }
  295.  
  296. "\n\nQuicksort %d ints on %d procs: %f secs\n",
  297. number_of_elements, number_of_process,
  298. time_taken);
  299. }
  300.  
  301. MPI_Finalize();
  302. return 0;
  303. }
  304.  
Success #stdin #stdout #stderr 0.27s 40424KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Error: unexpected '/' in "/"
Execution halted