#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mpi.h>
// Function to swap two elements
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// Function to partition the array
int partition(int arr[], int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] < pivot) {
i++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return i + 1;
}
// Function to implement quicksort
void quicksort(int arr[], int low, int high) {
if (low < high) {
int pivot = partition(arr, low, high);
quicksort(arr, low, pivot - 1);
quicksort(arr, pivot + 1, high);
}
}
// Function to merge two sorted arrays
void merge(int arr1[], int arr2[], int result[], int size1, int size2) {
int i = 0, j = 0, k = 0;
while (i < size1 && j < size2) {
if (arr1[i] < arr2[j]) {
result[k] = arr1[i];
i++;
} else {
result[k] = arr2[j];
j++;
}
k++;
}
while (i < size1) {
result[k] = arr1[i];
i++;
k++;
}
while (j < size2) {
result[k] = arr2[j];
j++;
k++;
}
}
int main(int argc, char** argv) {
int num_elements, num_processors, processor_id;
double start_time, end_time;
// Initialize MPI
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_processors);
MPI_Comm_rank(MPI_COMM_WORLD, &processor_id);
// Get the number of elements from the user
if (processor_id == 0) {
printf("Enter the number of elements (max 1000): "); scanf("%d", &num_elements
); if (num_elements < 1 || num_elements > 1000) {
printf("Invalid input. Please enter a value between 1 and 1000.\n"); MPI_Abort(MPI_COMM_WORLD, 1);
}
}
// Broadcast the number of elements to all processors
MPI_Bcast(&num_elements, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Generate random data
int* data
= (int*)malloc(num_elements
* sizeof(int)); if (processor_id == 0) {
for (int i = 0; i < num_elements; i++) {
}
}
// Distribute the data among processors
int chunk_size = num_elements / num_processors;
int* local_data
= (int*)malloc(chunk_size
* sizeof(int)); MPI_Scatter(data, chunk_size, MPI_INT, local_data, chunk_size, MPI_INT, 0, MPI_COMM_WORLD);
// Sort the local data
start_time = MPI_Wtime();
quicksort(local_data, 0, chunk_size - 1);
// Gather the sorted data
int* sorted_data
= (int*)malloc(num_elements
* sizeof(int)); MPI_Gather(local_data, chunk_size, MPI_INT, sorted_data, chunk_size, MPI_INT, 0, MPI_COMM_WORLD);
// Merge the sorted data
if (processor_id == 0) {
int* temp
= (int*)malloc(num_elements
* sizeof(int)); int offset = 0;
for (int i = 0; i < num_processors; i++) {
merge(sorted_data + offset, sorted_data + offset + chunk_size, temp + offset, chunk_size, chunk_size);
offset += chunk_size;
}
end_time = MPI_Wtime();
for (int i = 0; i < num_elements; i++) {
}
for (int i = 0; i < num_elements; i++) {
}
printf("Execution time: %f seconds\n", end_time
- start_time
); }
// Clean up
MPI_Finalize();
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHRpbWUuaD4KI2luY2x1ZGUgPG1waS5oPgoKLy8gRnVuY3Rpb24gdG8gc3dhcCB0d28gZWxlbWVudHMKdm9pZCBzd2FwKGludCAqYSwgaW50ICpiKSB7CiAgICBpbnQgdGVtcCA9ICphOwogICAgKmEgPSAqYjsKICAgICpiID0gdGVtcDsKfQoKLy8gRnVuY3Rpb24gdG8gcGFydGl0aW9uIHRoZSBhcnJheQppbnQgcGFydGl0aW9uKGludCBhcnJbXSwgaW50IGxvdywgaW50IGhpZ2gpIHsKICAgIGludCBwaXZvdCA9IGFycltoaWdoXTsKICAgIGludCBpID0gbG93IC0gMTsKICAgIGZvciAoaW50IGogPSBsb3c7IGogPCBoaWdoOyBqKyspIHsKICAgICAgICBpZiAoYXJyW2pdIDwgcGl2b3QpIHsKICAgICAgICAgICAgaSsrOwogICAgICAgICAgICBzd2FwKCZhcnJbaV0sICZhcnJbal0pOwogICAgICAgIH0KICAgIH0KICAgIHN3YXAoJmFycltpICsgMV0sICZhcnJbaGlnaF0pOwogICAgcmV0dXJuIGkgKyAxOwp9CgovLyBGdW5jdGlvbiB0byBpbXBsZW1lbnQgcXVpY2tzb3J0CnZvaWQgcXVpY2tzb3J0KGludCBhcnJbXSwgaW50IGxvdywgaW50IGhpZ2gpIHsKICAgIGlmIChsb3cgPCBoaWdoKSB7CiAgICAgICAgaW50IHBpdm90ID0gcGFydGl0aW9uKGFyciwgbG93LCBoaWdoKTsKICAgICAgICBxdWlja3NvcnQoYXJyLCBsb3csIHBpdm90IC0gMSk7CiAgICAgICAgcXVpY2tzb3J0KGFyciwgcGl2b3QgKyAxLCBoaWdoKTsKICAgIH0KfQoKLy8gRnVuY3Rpb24gdG8gbWVyZ2UgdHdvIHNvcnRlZCBhcnJheXMKdm9pZCBtZXJnZShpbnQgYXJyMVtdLCBpbnQgYXJyMltdLCBpbnQgcmVzdWx0W10sIGludCBzaXplMSwgaW50IHNpemUyKSB7CiAgICBpbnQgaSA9IDAsIGogPSAwLCBrID0gMDsKICAgIHdoaWxlIChpIDwgc2l6ZTEgJiYgaiA8IHNpemUyKSB7CiAgICAgICAgaWYgKGFycjFbaV0gPCBhcnIyW2pdKSB7CiAgICAgICAgICAgIHJlc3VsdFtrXSA9IGFycjFbaV07CiAgICAgICAgICAgIGkrKzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHRba10gPSBhcnIyW2pdOwogICAgICAgICAgICBqKys7CiAgICAgICAgfQogICAgICAgIGsrKzsKICAgIH0KICAgIHdoaWxlIChpIDwgc2l6ZTEpIHsKICAgICAgICByZXN1bHRba10gPSBhcnIxW2ldOwogICAgICAgIGkrKzsKICAgICAgICBrKys7CiAgICB9CiAgICB3aGlsZSAoaiA8IHNpemUyKSB7CiAgICAgICAgcmVzdWx0W2tdID0gYXJyMltqXTsKICAgICAgICBqKys7CiAgICAgICAgaysrOwogICAgfQp9CgppbnQgbWFpbihpbnQgYXJnYywgY2hhcioqIGFyZ3YpIHsKICAgIGludCBudW1fZWxlbWVudHMsIG51bV9wcm9jZXNzb3JzLCBwcm9jZXNzb3JfaWQ7CiAgICBkb3VibGUgc3RhcnRfdGltZSwgZW5kX3RpbWU7CgogICAgLy8gSW5pdGlhbGl6ZSBNUEkKICAgIE1QSV9Jbml0KCZhcmdjLCAmYXJndik7CiAgICBNUElfQ29tbV9zaXplKE1QSV9DT01NX1dPUkxELCAmbnVtX3Byb2Nlc3NvcnMpOwogICAgTVBJX0NvbW1fcmFuayhNUElfQ09NTV9XT1JMRCwgJnByb2Nlc3Nvcl9pZCk7CgogICAgLy8gR2V0IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgZnJvbSB0aGUgdXNlcgogICAgaWYgKHByb2Nlc3Nvcl9pZCA9PSAwKSB7CiAgICAgICAgcHJpbnRmKCJFbnRlciB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIChtYXggMTAwMCk6ICIpOwogICAgICAgIHNjYW5mKCIlZCIsICZudW1fZWxlbWVudHMpOwogICAgICAgIGlmIChudW1fZWxlbWVudHMgPCAxIHx8IG51bV9lbGVtZW50cyA+IDEwMDApIHsKICAgICAgICAgICAgcHJpbnRmKCJJbnZhbGlkIGlucHV0LiBQbGVhc2UgZW50ZXIgYSB2YWx1ZSBiZXR3ZWVuIDEgYW5kIDEwMDAuXG4iKTsKICAgICAgICAgICAgTVBJX0Fib3J0KE1QSV9DT01NX1dPUkxELCAxKTsKICAgICAgICB9CiAgICB9CgogICAgLy8gQnJvYWRjYXN0IHRoZSBudW1iZXIgb2YgZWxlbWVudHMgdG8gYWxsIHByb2Nlc3NvcnMKICAgIE1QSV9CY2FzdCgmbnVtX2VsZW1lbnRzLCAxLCBNUElfSU5ULCAwLCBNUElfQ09NTV9XT1JMRCk7CgogICAgLy8gR2VuZXJhdGUgcmFuZG9tIGRhdGEKICAgIGludCogZGF0YSA9IChpbnQqKW1hbGxvYyhudW1fZWxlbWVudHMgKiBzaXplb2YoaW50KSk7CiAgICBpZiAocHJvY2Vzc29yX2lkID09IDApIHsKICAgICAgICBzcmFuZCh0aW1lKE5VTEwpKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bV9lbGVtZW50czsgaSsrKSB7CiAgICAgICAgICAgIGRhdGFbaV0gPSByYW5kKCkgJSAxMDAwOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBEaXN0cmlidXRlIHRoZSBkYXRhIGFtb25nIHByb2Nlc3NvcnMKICAgIGludCBjaHVua19zaXplID0gbnVtX2VsZW1lbnRzIC8gbnVtX3Byb2Nlc3NvcnM7CiAgICBpbnQqIGxvY2FsX2RhdGEgPSAoaW50KiltYWxsb2MoY2h1bmtfc2l6ZSAqIHNpemVvZihpbnQpKTsKICAgIE1QSV9TY2F0dGVyKGRhdGEsIGNodW5rX3NpemUsIE1QSV9JTlQsIGxvY2FsX2RhdGEsIGNodW5rX3NpemUsIE1QSV9JTlQsIDAsIE1QSV9DT01NX1dPUkxEKTsKCiAgICAvLyBTb3J0IHRoZSBsb2NhbCBkYXRhCiAgICBzdGFydF90aW1lID0gTVBJX1d0aW1lKCk7CiAgICBxdWlja3NvcnQobG9jYWxfZGF0YSwgMCwgY2h1bmtfc2l6ZSAtIDEpOwoKICAgIC8vIEdhdGhlciB0aGUgc29ydGVkIGRhdGEKICAgIGludCogc29ydGVkX2RhdGEgPSAoaW50KiltYWxsb2MobnVtX2VsZW1lbnRzICogc2l6ZW9mKGludCkpOwogICAgTVBJX0dhdGhlcihsb2NhbF9kYXRhLCBjaHVua19zaXplLCBNUElfSU5ULCBzb3J0ZWRfZGF0YSwgY2h1bmtfc2l6ZSwgTVBJX0lOVCwgMCwgTVBJX0NPTU1fV09STEQpOwoKICAgIC8vIE1lcmdlIHRoZSBzb3J0ZWQgZGF0YQogICAgaWYgKHByb2Nlc3Nvcl9pZCA9PSAwKSB7CiAgICAgICAgaW50KiB0ZW1wID0gKGludCopbWFsbG9jKG51bV9lbGVtZW50cyAqIHNpemVvZihpbnQpKTsKICAgICAgICBpbnQgb2Zmc2V0ID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG51bV9wcm9jZXNzb3JzOyBpKyspIHsKICAgICAgICAgICAgbWVyZ2Uoc29ydGVkX2RhdGEgKyBvZmZzZXQsIHNvcnRlZF9kYXRhICsgb2Zmc2V0ICsgY2h1bmtfc2l6ZSwgdGVtcCArIG9mZnNldCwgY2h1bmtfc2l6ZSwgY2h1bmtfc2l6ZSk7CiAgICAgICAgICAgIG9mZnNldCArPSBjaHVua19zaXplOwogICAgICAgIH0KICAgICAgICBlbmRfdGltZSA9IE1QSV9XdGltZSgpOwogICAgICAgIHByaW50ZigiQWN0dWFsIGRhdGE6ICIpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtX2VsZW1lbnRzOyBpKyspIHsKICAgICAgICAgICAgcHJpbnRmKCIlZCAiLCBkYXRhW2ldKTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJcbiIpOwogICAgICAgIHByaW50ZigiU29ydGVkIGRhdGE6ICIpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbnVtX2VsZW1lbnRzOyBpKyspIHsKICAgICAgICAgICAgcHJpbnRmKCIlZCAiLCB0ZW1wW2ldKTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJcbiIpOwogICAgICAgIHByaW50ZigiRXhlY3V0aW9uIHRpbWU6ICVmIHNlY29uZHNcbiIsIGVuZF90aW1lIC0gc3RhcnRfdGltZSk7CiAgICAgICAgZnJlZSh0ZW1wKTsKICAgIH0KCiAgICAvLyBDbGVhbiB1cAogICAgZnJlZShkYXRhKTsKICAgIGZyZWUobG9jYWxfZGF0YSk7CiAgICBmcmVlKHNvcnRlZF9kYXRhKTsKICAgIE1QSV9GaW5hbGl6ZSgpOwogICAgcmV0dXJuIDA7Cn0=