Skip to content
Snippets Groups Projects
Commit ae86e025 authored by Chao Zhan's avatar Chao Zhan
Browse files

add MPI broadcast example

parent 647d5d00
No related branches found
No related tags found
No related merge requests found
Showing
with 17 additions and 589 deletions
PROG = round_trip PROG = broadcast
OBJECTS = round_trip.o OBJECTS = broadcast.o
CC = mpicc CC = mpicc
CFLAGS = -Wall -std=c11 CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path CFLAGS += -I. # add the current directory to the include path
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
int main(int argc, char **argv) { int main(int argc, char **argv) {
char token; int arg;
MPI_Status status;
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
// Get the number of processes // Get the number of processes
...@@ -23,17 +22,23 @@ int main(int argc, char **argv) { ...@@ -23,17 +22,23 @@ int main(int argc, char **argv) {
int name_len; int name_len;
MPI_Get_processor_name(processor_name, &name_len); MPI_Get_processor_name(processor_name, &name_len);
// all processes send to rank 0 if (rank == 0) {
if (rank != 0) {
token = 'A' + rank; if (argc == 1 || // the program is called without parameters
MPI_Send(&token, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD); (argc > 1 && !strcmp(argv[1], "-h")) // user asked for help )
} else { ) {
for (int i = 1; i < num_processes; i++) { printf("\nUsage: init [0-9]+\n");
MPI_Recv(&token, 1, MPI_CHAR, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status); MPI_Abort(MPI_COMM_WORLD, 1);
printf("Process 0 received token %c from process %d\n", token, status.MPI_SOURCE);
} }
arg = atoi(argv[1]);
} }
MPI_Bcast(&arg, 1, MPI_INT, 0, MPI_COMM_WORLD);
printf("Process %d of %d on %s: arg = %d\n", rank, num_processes,
processor_name, arg);
// Finalize the MPI environment. No more MPI calls can be made after this // Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize(); MPI_Finalize();
} }
PROG = deadlock
OBJECTS = deadlock.o
CC = mpicc
CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path
$(PROG): $(OBJECTS) # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
.Phone: run
run: $(PROG) # build and run the program
mpirun -np 2 ./$(PROG)
$(OBJECTS): %.o: %.c # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(PROG)
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
char message[32];
int err;
MPI_Status status;
MPI_Init(&argc, &argv);
// Get the number of processes
int num_processes;
MPI_Comm_size(MPI_COMM_WORLD, &num_processes);
// Get the rank of the process
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// forcing the program to run with exactly two processes
if (num_processes != 2) {
fprintf(stderr, "Must use exactly two processes for this program\n");
MPI_Abort(MPI_COMM_WORLD, 1);
} else {
if (rank == 0) {
err = MPI_Recv(message, 32, MPI_CHAR, 1, 0, MPI_COMM_WORLD, &status);
if (err == MPI_SUCCESS)
printf("[%s] Message received: %s\n", processor_name, message);
strncpy(message, "Message from process #0", 32);
err = MPI_Send(message, 32, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
if (err == MPI_SUCCESS)
printf("[%s] Message sent: %s\n", processor_name, message);
} else {
err = MPI_Recv(message, 32, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
if (err == MPI_SUCCESS)
printf("[%s] Message received: %s\n", processor_name, message);
strncpy(message, "Message from process #1", 32);
err = MPI_Send(message, 32, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
if (err == MPI_SUCCESS)
printf("[%s] Message sent: %s\n", processor_name, message);
}
}
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
PROG = deadlock_2
OBJECTS = deadlock_2.o
CC = mpicc
CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path
$(PROG): $(OBJECTS) # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
.Phone: run
run: $(PROG) # build and run the program
mpirun -np 2 ./$(PROG)
$(OBJECTS): %.o: %.c # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(PROG)
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
char *sendbuf, *recvbuf;
MPI_Status status;
MPI_Init(&argc, &argv);
// Get the number of processes
int num_processes;
MPI_Comm_size(MPI_COMM_WORLD, &num_processes);
// Get the rank of the process
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// forcing the program to run with exactly two processes
if (num_processes != 2) {
fprintf(stderr, "Must use exactly two processes for this program\n");
MPI_Abort(MPI_COMM_WORLD, 1);
} else {
int other = 1 - rank;
// testing different message sizes that will cause deadlock
for (int size = 1; size < 2000000000; size *= 10) {
sendbuf = malloc(size * sizeof(char));
recvbuf = malloc(size * sizeof(char));
if (!sendbuf || !recvbuf) {
fprintf(stderr, "Failed to allocate memory\n");
MPI_Abort(MPI_COMM_WORLD, 1);
}
MPI_Send(sendbuf, size, MPI_CHAR, other, 0, MPI_COMM_WORLD);
MPI_Recv(recvbuf, size, MPI_CHAR, other, 0, MPI_COMM_WORLD, &status);
if (rank == 0) {
printf("Send did not block for %d bytes\n",size);
}
free(sendbuf);
free(recvbuf);
}
}
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
PROG = hello_world
OBJECTS = hello_world.o
CC = mpicc
CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path
$(PROG): $(OBJECTS) # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
.Phone: run
run: $(PROG) # build and run the program
mpirun ./$(PROG)
$(OBJECTS): %.o: %.c # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(PROG)
#include <mpi.h>
#include <stdio.h>
int main(int argc, char **argv) {
// Initialize the MPI environment.
MPI_Init(&argc, &argv);
// Get the number of processes
int num_processes;
MPI_Comm_size(MPI_COMM_WORLD, &num_processes);
// Get the rank of the process
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// Print off a hello world message
printf("Hello world, processor: %s, rank: %d, total num of processors: %d\n",
processor_name, rank, num_processes);
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
PROG = nb_point_2_point
OBJECTS = nb_point_2_point.o
CC = mpicc
CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path
$(PROG): $(OBJECTS) # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
.Phone: run
run: $(PROG) # build and run the program
mpirun -np 2 ./$(PROG)
$(OBJECTS): %.o: %.c # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(PROG)
#include <mpi.h>
#include <stdio.h>
#include <string.h>
static void busy(void) {
int i;
for (i = 0; i < 10000000; i++) {
if (i % 5000000 == 0) {
printf("Busy...\n");
fflush(stdout);
}
}
printf("Busy...\n");
}
int main(int argc, char **argv) {
char message[32];
MPI_Status status;
MPI_Request request;
MPI_Init(&argc, &argv);
// Get the number of processes
int num_processes;
MPI_Comm_size(MPI_COMM_WORLD, &num_processes);
// Get the rank of the process
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// forcing the program to run with exactly two processes
if (num_processes != 2) {
fprintf(stderr, "Must use exactly two processes for this program\n");
MPI_Abort(MPI_COMM_WORLD, 1);
} else {
if (rank == 0) {
strncpy(message, "This is not a message!", 32);
MPI_Isend(message, 32, MPI_CHAR, 1, 0, MPI_COMM_WORLD, &request);
busy();
MPI_Wait(&request, &status);
printf("[%s] Message sent: %s\n", processor_name, message);
} else {
MPI_Irecv(message, 32, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &request);
busy();
MPI_Wait(&request, &status);
printf("[%s] Message received: %s\n", processor_name, message);
}
}
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
PROG = nb_waitall
OBJECTS = nb_waitall.o
CC = mpicc
CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path
$(PROG): $(OBJECTS) # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
.Phone: run
run: $(PROG) # build and run the program
mpirun ./$(PROG);
$(OBJECTS): %.o: %.c # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(PROG)
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
MPI_Init(&argc, &argv);
// Get the number of processes
int num_processes;
MPI_Comm_size(MPI_COMM_WORLD, &num_processes);
// Get the rank of the process
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Request *requests =
(MPI_Request *) malloc(num_processes * sizeof(MPI_Request));
MPI_Status *statuses =
(MPI_Status *) malloc(num_processes * sizeof(MPI_Status));
char *recv_buffers = (char *)malloc(num_processes * sizeof(char));
char send_buffers = 'A';
send_buffers += rank;
MPI_Isend(&send_buffers, 1, MPI_CHAR, 0, 0,
MPI_COMM_WORLD, &requests[rank]);
// all processes send to rank 0
if (rank == 0) {
for (int i = 0; i < num_processes; i++)
MPI_Irecv(&recv_buffers[i], 1, MPI_CHAR, i, 0,
MPI_COMM_WORLD, &requests[i]);
MPI_Waitall(num_processes, requests, statuses);
for (int i = 0; i < num_processes; i++) {
printf("Process 0 received token %c from process %d\n", recv_buffers[i],
statuses[i].MPI_SOURCE);
}
}
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
PROG = ordering
OBJECTS = ordering.o
CC = mpicc
CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path
$(PROG): $(OBJECTS) # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
.Phone: run
run: $(PROG) # build and run the program
mpirun -np 2 ./$(PROG)
$(OBJECTS): %.o: %.c # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(PROG)
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
char token;
MPI_Status status;
MPI_Init(&argc, &argv);
// Get the number of processes
int num_processes;
MPI_Comm_size(MPI_COMM_WORLD, &num_processes);
// Get the rank of the process
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// forcing the program to run with exactly two processes
if (num_processes != 2) {
fprintf(stderr, "Must use exactly two processes for this program\n");
MPI_Abort(MPI_COMM_WORLD, 1);
} else {
if (rank == 0) {
token = 'A';
MPI_Send(&token, 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
token = 'B';
MPI_Send(&token, 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
token = 'C';
MPI_Send(&token, 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
} else {
sleep(1);
MPI_Recv(&token, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
printf("Process 1 received token %c from process 0\n", token);
MPI_Recv(&token, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
printf("Process 1 received token %c from process 0\n", token);
MPI_Recv(&token, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
printf("Process 1 received token %c from process 0\n", token);
}
}
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
PROG = ordering_2
OBJECTS = ordering_2.o
CC = mpicc
CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path
$(PROG): $(OBJECTS) # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
.Phone: run
run: $(PROG) # build and run the program
for i in `seq 3`; do \
echo "Run $$i:"; \
mpirun ./$(PROG); \
done
$(OBJECTS): %.o: %.c # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(PROG)
PROG = point_2_point
OBJECTS = point_2_point.o
CC = mpicc
CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path
$(PROG): $(OBJECTS) # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
.Phone: run
run: $(PROG) # build and run the program
mpirun -np 2 ./$(PROG)
$(OBJECTS): %.o: %.c # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(PROG)
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
char message[32];
int err;
MPI_Status status;
MPI_Init(&argc, &argv);
// Get the number of processes
int num_processes;
MPI_Comm_size(MPI_COMM_WORLD, &num_processes);
// Get the rank of the process
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// Get the name of the processor
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name, &name_len);
// forcing the program to run with exactly two processes
if (num_processes != 2) {
fprintf(stderr, "Must use exactly two processes for this program\n");
MPI_Abort(MPI_COMM_WORLD, 1);
} else {
if (rank == 0) {
strncpy(message, "This is not a message!", 32);
err = MPI_Send(message, 32, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
if (err == MPI_SUCCESS)
printf("[%s] Message sent: %s\n", processor_name, message);
} else {
err = MPI_Recv(message, 32, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
if (err == MPI_SUCCESS)
printf("[%s] Message received: %s\n", processor_name, message);
}
}
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
OBJECTS = q1.o q2.o q3.o q4.o q5.o
CC = mpicc
CFLAGS = -Wall -std=c11
CFLAGS += -I. # add the current directory to the include path
PHONY_RUNS = run1 run2 run3 run4 run5
PHONY_CLEANS = clean1 clean2 clean3 clean4 clean5
.PHONY: all
all: $(patsubst %.o,%,$(OBJECTS)) # build all binaries
.PHONY: $(PHONY_RUNS)
$(PHONY_RUNS): run%: q% # run a binary
time mpirun $<
$(patsubst %.o,%,$(OBJECTS)): %: %.o # link the object files into a binary
$(CC) $(CFLAGS) $^ -o $@
$(OBJECTS): %.o: %.c # compile the source files into object files
$(CC) $(CFLAGS) -c $<
.PHONY: clean
clean: # remove the object files and the binary
rm -f $(OBJECTS) $(patsubst %.o,%,$(OBJECTS))
.PHONY: $(PHONY_RUNS)
$(PHONY_CLEANS): clean%: q% # run a binary
rm -f $<.o $<
# Code from the questions
This folder contains all the programs that are presented in the question PDF.
## Build
```c
# build all programs
make
# run specific program
make run1
make run2
...
make run5
# clean specific build
make clean1
make clean2
...
make clean5
# clean all builds
make clean
```
#include <mpi.h>
#include <stdio.h>
int main(int argc, char **argv) {
int sbuffer = 1;
int rbuffer = 2;
const int buflen = 1;
MPI_Init(&argc, &argv);
// Get the number of processes
int nprocs;
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
// Get the rank of the process
int procid;
MPI_Comm_rank(MPI_COMM_WORLD, &procid);
for (int p = 0; p < nprocs; p++) {
if (p != procid)
MPI_Send(&sbuffer, buflen, MPI_INT, p, 0, MPI_COMM_WORLD);
printf("Process %d blocking sent message to process %d\n", procid, p);
}
for (int p = 0; p < nprocs; p++) {
if (p != procid)
MPI_Recv(&rbuffer, buflen, MPI_INT, p, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process %d blocking received message from process %d\n", procid, p);
}
// Finalize the MPI environment. No more MPI calls can be made after this
MPI_Finalize();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment