Commit e38409ab authored by julanar.ali's avatar julanar.ali

Initial commit

parents
# Makefile for MPI program
# Source file
SRC = prefix_sum.cpp
# number of process
NP = 4
# Compiler
CXX = mpic++
# Executable name
EXE = ./output
all: $(EXE)
$(EXE): $(SRC)
$(CXX) -o $(EXE) $(SRC)
clean:
rm -f $(EXE)
run:
mpirun -np $(NP) -f hosts $(EXE)
\ No newline at end of file
master
slave1 user=mpiuser
slave2 user=mpiuser
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <cstring>
void prefix_mpi(int* block_array, int block_size, int* block_prefix, MPI_Comm communicator)
{
int my_rank, com_size;
MPI_Comm_rank(communicator, &my_rank);
MPI_Comm_size(communicator, &com_size);
int* local_prefix = (int*)malloc(block_size * sizeof(int));
local_prefix[0] = block_array[0];
int sum;
// Calculate local prefix sum
for (int i = 1; i < block_size; i++) {
local_prefix[i] = local_prefix[i - 1] + block_array[i];
}
sum = local_prefix[block_size - 1]; //the total sum of each block
int* prefix_sums = (int*)malloc(com_size * sizeof(int)); //contains the total sums for blocks in it
MPI_Gather(&sum, 1, MPI_INT, prefix_sums, 1, MPI_INT, 0, communicator);
//to store the values that should be added to each local_prefix
int* accumulator= (int*)malloc(com_size * sizeof(int));
if (my_rank == 0) {
accumulator[0] = 0;
for (int i = 1; i < com_size; i++) {
//doing prefix_sum to accumulator
accumulator[i] = accumulator[i-1] + prefix_sums[i-1];
}
}
MPI_Bcast(accumulator, com_size, MPI_INT, 0, communicator);
//block_prefix contains the final prefix sum for a clock
for (int i = 0; i < block_size; i++) {
block_prefix[i] = local_prefix[i] + accumulator[my_rank];
}
free(local_prefix);
free(prefix_sums);
}
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
int my_rank;
int com_size;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &com_size);
int total_array_size = 20;
if (total_array_size % com_size != 0)
total_array_size = (total_array_size / com_size + 1) * com_size;
int block_size = total_array_size / com_size;
int* total_array = NULL;
int* total_prefix = NULL;
if (my_rank == 0) {
total_array = (int*)malloc(total_array_size * sizeof(int));
total_prefix = (int*)malloc(total_array_size * sizeof(int));
for (int i = 0; i < total_array_size; i++)
total_array[i] = rand() % 11;
printf("Total Array: ");
for (int i = 0; i < total_array_size; i++)
printf("%d ", total_array[i]);
printf("\n\n");
}
int* block_array = (int*)malloc(block_size * sizeof(int));
int* block_prefix = (int*)malloc(block_size * sizeof(int));
MPI_Scatter(total_array, block_size, MPI_INT,
block_array, block_size, MPI_INT, 0, MPI_COMM_WORLD);
prefix_mpi(block_array, block_size, block_prefix, MPI_COMM_WORLD);
MPI_Gather(block_prefix, block_size, MPI_INT,
total_prefix, block_size, MPI_INT, 0, MPI_COMM_WORLD);
int accum = 0;
if (my_rank == 0) {
for (int i = 1; i < total_array_size; i++) {
accum += total_array[i - 1];
if (total_prefix[i-1] != accum)
printf("Error at index %i: %i expected, %i computed\n", i, accum, total_prefix[i]);
}
printf("Prefix sum for the array is :\n");
for (int i = 1; i < total_array_size; i++) {
printf("%d ",total_prefix[i]);
}
printf("\n\n");
printf("Test completed!\n");
free(total_array);
free(total_prefix);
}
free(block_array);
free(block_prefix);
MPI_Finalize();
return 0;
}
# Makefile for MPI program
# Source file
SRC = reduce_mpi.cpp
# number of process
NP = 4
# Compiler
CXX = mpic++
# Executable name
EXE = ./output
all: $(EXE)
$(EXE): $(SRC)
$(CXX) -o $(EXE) $(SRC)
clean:
rm -f $(EXE)
run:
mpirun -np $(NP) -f hosts $(EXE)
master
slave1 user=mpiuser
slave2 user=mpiuser
#include <mpi.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdbool.h>
void reduce_tree(
int* send_data,
int* recv_data,
int count,
MPI_Comm communicator)
{
int my_rank;
int com_size;
MPI_Comm_rank(communicator, &my_rank);
MPI_Comm_size(communicator, &com_size);
int parent = (my_rank - 1) / 2; // Calculate the parent_rank index in the tree
int left_rank = 2 * my_rank + 1; // Calculate left_child_rank index in the tree
int right_rank= 2 * my_rank + 2; // Calculate the right_child_rank index in the tree
if(my_rank != 0){
recv_data = (int*)malloc(count * sizeof(int));
}
//initializing recv_data with zeros
memset(recv_data, 0, count * sizeof(int));
// these buffers are for storing the received data from left and right children
int* left_data = (int*)malloc(count * sizeof(int));
int* right_data = (int*)malloc(count * sizeof(int));
// Receiving data from left child
if (left_rank < com_size) {
MPI_Recv(left_data, count, MPI_INT, left_rank, 0, communicator, MPI_STATUS_IGNORE);
for (int i = 0; i < count; i++) {
recv_data[i] = left_data[i] + recv_data[i];
}
}
// Receiving data from right child
if (right_rank < com_size) {
MPI_Recv(right_data, count, MPI_INT, right_rank, 0, communicator, MPI_STATUS_IGNORE);
for (int i = 0; i < count; i++) {
recv_data[i] = right_data[i] + recv_data[i];
}
}
// adding data received from children with parent data
for (int i = 0; i < count; i++) {
recv_data[i] = recv_data[i] + send_data[i];
}
// Sending the result to the parent unless it is the root
if (my_rank != 0) {
MPI_Send(recv_data, count, MPI_INT, parent, 0, communicator);
}
// Free allocated memory
free(left_data);
free(right_data);
}
void reduce_sequential(
int* send_data,
int* recv_data,
int count,
MPI_Comm communicator)
{
int my_rank;
int com_size;
MPI_Comm_rank(communicator, &my_rank);
MPI_Comm_size(communicator, &com_size);
int* gather_buffer = NULL;
if (my_rank == 0)
{
gather_buffer = (int*) calloc(count * com_size, sizeof(int));
}
MPI_Gather(send_data, count, MPI_INT, gather_buffer, count, MPI_INT, 0, communicator);
if (my_rank == 0)
{
memset(recv_data, 0, count * sizeof(int));
for (int p = 0; p < com_size; p++)
for (int i = 0; i < count; i++)
recv_data[i] += gather_buffer[count * p + i];
free(gather_buffer);
}
}
int main(int argc, char** args)
{
MPI_Init(&argc, &args);
int count = 10;
int max_value = 64;
int* recv_array_tree = NULL;
int* recv_array_sequential = NULL;
int my_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm communicator = MPI_COMM_WORLD;
int com_size;
MPI_Comm_size(communicator, &com_size);
if (my_rank == 0)
{
recv_array_tree = (int*) malloc(count * sizeof(int));
recv_array_sequential = (int*) malloc(count * sizeof(int));
}
int* send_array = (int*)malloc(count * sizeof(int));
for (int i = 0; i < count; i++)
send_array[i] = my_rank;
MPI_Barrier(MPI_COMM_WORLD);
double time_start = MPI_Wtime();
reduce_tree(send_array, recv_array_tree, count, MPI_COMM_WORLD);
double time_end = MPI_Wtime();
double elapsed_time = time_end - time_start;
MPI_Barrier(MPI_COMM_WORLD);
double time_start_seq = MPI_Wtime();
reduce_sequential(send_array, recv_array_sequential, count, MPI_COMM_WORLD);
time_end = MPI_Wtime();
double elapsed_time_seq = time_end - time_start_seq;
printf("\n");
if (my_rank == 0)
{
printf("size of array : %d \n", count);
printf("Number of processes: %d\n", com_size);
printf("Processing time for reduce tree is: %lf\n", elapsed_time);
printf("Processing time for reduce sequential is: %lf\n\n", elapsed_time_seq);
for (int i = 0; i < count; i++)
if (recv_array_tree[i] == recv_array_sequential[i])
printf("At index %i: reduce_tree is %i, reduce_sequential is %i\n",
i, recv_array_tree[i], recv_array_sequential[i]);
free(recv_array_tree);
free(recv_array_sequential);
}
free(send_array);
MPI_Finalize();
return 0;
}
Markdown is supported
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