Commit 06ae5bc9 authored by amira's avatar amira

Final commit

parents
File added
master
slave1 user=mpiuser
slave2 user=mpiuser
File added
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int* create_rand_nums(int size) {
int* rand_nums = (int*)malloc(sizeof(int) * size);
for (int i = 0; i < size; i++) {
// Generating random numbers between 0 and 1 for demonstration purposes
rand_nums[i] = (int)rand() % 10;
}
return rand_nums;
}
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
// Assuming block_size is defined and initialized
int in_length = 16;
int block_size = in_length / world_size;
int* rand_nums = NULL;
if (world_rank == 0) {
rand_nums = create_rand_nums(in_length);
}
// Create a buffer that will hold a subset of the random numbers
int* sub_rand_nums = (int*)malloc(sizeof(int) * block_size);
int* block_prefix = (int*)malloc(sizeof(int) * block_size);
// Scatter the random numbers to all processes
MPI_Scatter(rand_nums, block_size, MPI_INT, sub_rand_nums,
block_size, MPI_INT, 0, MPI_COMM_WORLD);
// Compute the average of your subset
block_prefix[0] = sub_rand_nums[0];
for(int i = 1; i < block_size; i++){
block_prefix[i] = block_prefix[i-1] + sub_rand_nums[i];
}
int sum = block_prefix[block_size - 1];
// Gather all partial averages down to the root process
int* block_sum = NULL;
if (world_rank == 0) {
block_sum = (int*)malloc(sizeof(int) * world_size);
}
MPI_Gather(&sum, 1, MPI_INT, block_sum, 1, MPI_INT, 0, MPI_COMM_WORLD);
int* prefix_block_sum = NULL;
if (world_rank == 0) {
prefix_block_sum = (int*)malloc(sizeof(int) * world_size);
prefix_block_sum[0] = 0;
for(int i = 1; i < world_size; i++){
prefix_block_sum[i] = prefix_block_sum[i-1] + block_sum[i-1];
}
}
int pre;
MPI_Scatter(prefix_block_sum, 1, MPI_INT, &pre,
1, MPI_INT, 0, MPI_COMM_WORLD);
for(int i = 0; i < block_size; i++){
block_prefix[i] += pre;
}
int* out = NULL;
if (world_rank == 0) {
out = (int*)malloc(sizeof(int) * in_length);
}
MPI_Gather(block_prefix, block_size, MPI_INT, out, block_size, MPI_INT, 0, MPI_COMM_WORLD);
// Compute the total average of all numbers.
if (world_rank == 0) {
printf("Input Array: ");
for(int i = 0; i < in_length; i++){
printf("%d ", rand_nums[i]);
}
printf("\nPrefix-Sum Array: ");
for(int i = 0; i < in_length; i++){
printf("%d ", out[i]);
}
printf("\n");
}
free(rand_nums);
free(sub_rand_nums);
free(block_sum);
MPI_Finalize();
return 0;
}
File added
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
#include <time.h>
int tree_reduce(int *send_data, int *recv_data, int count, MPI_Comm comm) {
int rank_in, np;
MPI_Comm_rank(MPI_COMM_WORLD, &rank_in);
MPI_Comm_size(MPI_COMM_WORLD, &np);
int rank = rank_in;
int num = np;
int depth = 1;
// many sends during a reduce process
while(num > 1) {
if(rank < num) {
if(rank % 2 != 0) {
MPI_Send(send_data, count, MPI_INT, (rank - 1) * depth, 0, comm);
rank *= num;
break; // one process can only send once
} else {
if(rank != (num - 1)) {
MPI_Recv(recv_data, count, MPI_INT, (rank + 1) * depth, 0, comm, MPI_STATUS_IGNORE);
for (int i = 0; i < count; i++) {
send_data[i] += recv_data[i];
}
}
rank /= 2;
}
depth *= 2;
}
num = num / 2 + (num%2);
}
// last reduce
if(rank_in == 0) {
int typesize;
MPI_Type_size(MPI_INT, &typesize);
memcpy(recv_data, send_data, count * typesize);
}
return 0;
}
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 *argv[])
{
int np, rank;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &np);
int i = rank + 1, j = rank + 1, sum_par = 0, sum_seq = 0;
//MPI_Type_size(ctype, &size);
clock_t par_start_time = clock();
tree_reduce(&i, &sum_par, 1, MPI_COMM_WORLD);
clock_t par_end_time = clock();
double parallel_time = ((double) (par_end_time - par_start_time)) / CLOCKS_PER_SEC;
clock_t seq_start_time = clock();
reduce_sequential(&j, &sum_seq, 1, MPI_COMM_WORLD);
clock_t seq_end_time = clock();
double sequential_time = ((double) (seq_end_time - seq_start_time)) / CLOCKS_PER_SEC;
// output result
if(rank == 0) {
printf("reduce_tree is %d with time %f, reduce_sequential is %d with time %f\n",
sum_par, parallel_time, sum_seq, sequential_time);
}
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