progress
This commit is contained in:
parent
2cbc7ef7ac
commit
8533db7eb2
5 changed files with 134 additions and 4 deletions
|
@ -1,2 +1,2 @@
|
|||
CompileFlags:
|
||||
Add: -I/usr/lib/aarch64-linux-gnu/openmpi/include -I/usr/lib/aarch64-linux-gnu/openmpi/include/openmpi
|
||||
Add: -I/usr/lib/aarch64-linux-gnu/openmpi/include -I/usr/lib/aarch64-linux-gnu/openmpi/include/openmpi
|
||||
|
|
4
assignments/02/.gitignore
vendored
4
assignments/02/.gitignore
vendored
|
@ -1,2 +1,4 @@
|
|||
qs_mpi
|
||||
*.o
|
||||
*.o
|
||||
compile_commands.json
|
||||
.cache
|
|
@ -11,7 +11,7 @@ LDFLAGS += $(shell pkg-config --libs mpi)
|
|||
all: qs_mpi
|
||||
|
||||
qs_mpi: qs_mpi.o
|
||||
$(CC) $(LDFLAGS) -o $@ $^
|
||||
$(CC) $^ $(CFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
qs_mpi.o: qs_mpi.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $^
|
||||
|
|
0
assignments/02/output.txt
Normal file
0
assignments/02/output.txt
Normal file
|
@ -1,6 +1,134 @@
|
|||
#include <mpi.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void local_quicksort(int *arr, int lo, int hi);
|
||||
char *string_of_list(int *arr, int len);
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
//
|
||||
int rank, p;
|
||||
MPI_Init(&argc, &argv);
|
||||
|
||||
int n = atoi(argv[1]);
|
||||
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &p);
|
||||
|
||||
// Generate integers
|
||||
int n_over_p = n / p;
|
||||
int integers[n_over_p];
|
||||
|
||||
// Important implementation detail: srand(0) is specially handled by glibc to
|
||||
// behave as if it was called with srand(1). To get around this, I'm seeding
|
||||
// with rank + 1
|
||||
//
|
||||
// See more: https://stackoverflow.com/a/27386563
|
||||
srand(rank + 1);
|
||||
|
||||
for (int i = 0; i < n_over_p; ++i) {
|
||||
// TODO: For readability during debugging, I'm capping this
|
||||
integers[i] = rand() % 101;
|
||||
// printf(" - %d\n", integers[i]);
|
||||
}
|
||||
|
||||
int group_root = 0;
|
||||
|
||||
// Locally sort
|
||||
printf("[%d] Numbers before: %s\n", rank,
|
||||
string_of_list(integers, n_over_p));
|
||||
local_quicksort(integers, 0, n_over_p);
|
||||
printf("[%d] Numbers after first sort: %s\n", rank,
|
||||
string_of_list(integers, n_over_p));
|
||||
|
||||
// Select a pivot.
|
||||
// This pivot is broadcasted to all nodes
|
||||
int pivot;
|
||||
|
||||
// The pivot is selected as the median (see chp. 9.4.4)
|
||||
// Not the real median though, need an existing element of the array
|
||||
pivot = integers[n_over_p / 2];
|
||||
MPI_Bcast(&pivot, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
||||
|
||||
printf("Median: %d\n", pivot);
|
||||
|
||||
// Determine where the boundary between S (lower) and L (higher) lies
|
||||
int boundary;
|
||||
for (int i = 0; i < n_over_p; ++i) {
|
||||
if (integers[i] >= pivot) {
|
||||
boundary = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int S_lo = 0, S_hi = boundary - 1;
|
||||
int L_lo = boundary, L_hi = n_over_p - 1;
|
||||
int S_size = S_hi - S_lo + 1, L_size = L_hi - L_lo + 1;
|
||||
// printf("[%d] S: [%d - %d] (%d), L: [%d - %d] (%d)\n", rank, S_lo, S_hi,
|
||||
// S_size, L_lo, L_hi, L_size);
|
||||
|
||||
// Perform global arrangement
|
||||
int S_global_end, L_global_end;
|
||||
MPI_Scan(&S_size, &S_global_end, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
|
||||
MPI_Scan(&L_size, &L_global_end, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
|
||||
|
||||
int S_global_start = S_global_end - S_size,
|
||||
L_global_start = L_global_end - L_size;
|
||||
printf("[%d] S: [%d - %d], L: [%d - %d]\n", rank, S_global_start,
|
||||
S_global_end - 1, L_global_start, L_global_end - 1);
|
||||
|
||||
// Send it to the correct target
|
||||
|
||||
// The first node is responsible for collecting all the data and then printing
|
||||
// it out to the file
|
||||
// MPI_Gather(const void *sendbuf, int sendcount, MPI_INT, void *recvbuf,
|
||||
// int recvcount, MPI_INT, 0, MPI_COMM_WORLD);
|
||||
if (rank == 0) {
|
||||
FILE *f = fopen(argv[2], "w");
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
MPI_Finalize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// hi not inclusive
|
||||
void local_quicksort(int *arr, int lo, int hi) {
|
||||
int temp;
|
||||
|
||||
if (lo >= hi || lo < 0)
|
||||
return;
|
||||
|
||||
int pivot = arr[hi - 1];
|
||||
int pivot_idx = lo - 1;
|
||||
for (int j = lo; j < hi; ++j) {
|
||||
if (arr[j] < pivot) {
|
||||
pivot_idx += 1;
|
||||
|
||||
temp = arr[j];
|
||||
arr[j] = arr[pivot_idx];
|
||||
arr[pivot_idx] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
pivot_idx += 1;
|
||||
temp = arr[hi - 1];
|
||||
arr[hi - 1] = arr[pivot_idx];
|
||||
arr[pivot_idx] = temp;
|
||||
|
||||
// Recursive call
|
||||
local_quicksort(arr, lo, pivot_idx);
|
||||
local_quicksort(arr, pivot_idx + 1, hi);
|
||||
}
|
||||
|
||||
char *string_of_list(int *arr, int len) {
|
||||
char *buffer = malloc(1000);
|
||||
int offset = 0; // Keep track of the current position in the buffer
|
||||
for (int i = 0; i < len; i++) {
|
||||
offset += sprintf(buffer + offset, "%d", arr[i]);
|
||||
if (i < len - 1) {
|
||||
// Add a separator (e.g., comma or space) if it's not the last element
|
||||
offset += sprintf(buffer + offset, " ");
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
Loading…
Reference in a new issue