Skip to content
Snippets Groups Projects
Commit 01fddaab authored by Josep Marcello's avatar Josep Marcello :disappointed_relieved:
Browse files

feat: finish parallel merge sort for arbitrary process size

parent 9b94b582
Branches
......@@ -2,6 +2,7 @@
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Procedure merge_array
......@@ -107,9 +108,9 @@ int main() {
MPI_Bcast(&arr_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
// split array to processes
// -*- split array to processes -*-
int local_arr_size = arr_size / world_size + arr_size % world_size;
int local_arr[local_arr_size];
int local_arr[arr_size];
int *displs = NULL;
int *counts = NULL;
......@@ -126,14 +127,12 @@ int main() {
counts[i] = local_arr_size - (i != 0 ? arr_size % world_size : 0);
displs[i] = next_displ;
next_displ = counts[i] + displs[i];
// printf("%d: counts %d\tdispls %d\n", i, counts[i], displs[i]);
}
// printf("\n");
} else {
local_arr_size -= arr_size % world_size;
}
// send the array to all nodes
MPI_Scatterv(
arr,
counts,
......@@ -145,82 +144,97 @@ int main() {
0,
MPI_COMM_WORLD
);
// -*- finish splitting arrays -*-
// finish splitting arrays
// sort arrays
// sort local array
merge_sort(local_arr, 0, local_arr_size - 1);
// printf("before rank %d: ", my_rank);
// for (int i = 0; i < local_arr_size; ++i) {
// printf("%d, ", local_arr[i]);
// }
// printf("\n");
// send sort result to be merged
int recv_arr_sz = 0;
if (my_rank % 2 == 0) {
MPI_Recv(
&recv_arr_sz,
1,
MPI_INT,
my_rank + 1,
my_rank,
MPI_COMM_WORLD,
MPI_STATUS_IGNORE
);
} else {
MPI_Send(
&local_arr_size,
1,
MPI_INT,
my_rank - 1,
my_rank - 1,
MPI_COMM_WORLD
);
}
int recv_arr[recv_arr_sz];
if (my_rank % 2 == 0) {
MPI_Recv(
recv_arr,
recv_arr_sz,
MPI_INT,
my_rank + 1,
my_rank,
MPI_COMM_WORLD,
MPI_STATUS_IGNORE
);
} else {
MPI_Send(
local_arr,
local_arr_size,
MPI_INT,
my_rank - 1,
my_rank - 1,
MPI_COMM_WORLD
);
}
if (my_rank % 2 == 0) {
int total_sz = local_arr_size + recv_arr_sz;
int total_arr[local_arr_size + recv_arr_sz];
merge_two_arrays(local_arr, local_arr_size, recv_arr, recv_arr_sz, total_arr);
printf("after rank %d: ", my_rank);
for (int i = 0; i < total_sz; ++i) {
printf("%d, ", total_arr[i]);
for (int i = 2; i < world_size * 2 && my_rank % (i/2) == 0; i *= 2) {
int recv_arr_sz = 0;
int target_rank = my_rank + (my_rank % i == 0 ? 1 : -1) * i/2;
if (target_rank < world_size) {
// receive array
// start by sending or receiving the size of the array
if (my_rank % i == 0) {
MPI_Recv(
&recv_arr_sz,
1,
MPI_INT,
target_rank,
my_rank,
MPI_COMM_WORLD,
MPI_STATUS_IGNORE
);
} else {
MPI_Send(
&local_arr_size,
1,
MPI_INT,
target_rank,
target_rank,
MPI_COMM_WORLD
);
}
// create receive array buffer
int recv_arr[recv_arr_sz];
// now send or receive the array
if (my_rank % i == 0) {
MPI_Recv(
recv_arr,
recv_arr_sz,
MPI_INT,
target_rank,
my_rank,
MPI_COMM_WORLD,
MPI_STATUS_IGNORE
);
} else {
MPI_Send(
local_arr,
local_arr_size,
MPI_INT,
target_rank,
target_rank,
MPI_COMM_WORLD
);
}
// merge the local array and recieved array
if (my_rank % i == 0) {
// create output array
int total_sz = local_arr_size + recv_arr_sz;
int total_arr[local_arr_size + recv_arr_sz];
merge_two_arrays(
local_arr,
local_arr_size,
recv_arr,
recv_arr_sz,
total_arr
);
// copy output array to the local array
local_arr_size = total_sz;
memcpy(local_arr, total_arr, local_arr_size * sizeof(int));
}
}
printf("\n");
}
if (my_rank == 0) {
free(arr);
free(displs);
free(counts);
// output
for (int i = 0; i < local_arr_size; ++i) {
printf("%d, ", local_arr[i]);
}
printf("\n");
}
MPI_Finalize();
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment