# Chapter 5 (Basic MPI) > Program got 3 important element > 1) Communication - Within the communicator only processes inside communicator can communicate with each other > 2) Process - Can be identified by rank > 3) Message ## Code ### Find out important element #### Initialize MPI ```cpp int mpi; mpi = MPI_init(&argc, &argv); //important to init first ``` #### Terminate MPI ```cpp int mpi; mpi = MPI_init(&argc, &argv); //important to init first mpi = MPI_Finalize(); //once tak pakai, terminate it (optional) ``` #### Total number of processes ```cpp int mpi, numProcesses; mpi = MPI_init(&argc, &argv); //important to init first mpi = MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); //find total number of processes in a communication printf("Total number of process is: %d\n", numProcesses); ``` ```bash ┌──(aan㉿aan)-[~/HPPC] └─$ mpirun -np 1 helloworld Total number of process is: 1 ``` ```bash ┌──(aan㉿aan)-[~/HPPC] └─$ mpirun -np 2 helloworld Total number of process is: 2 Total number of process is: 2 ``` #### Exact rank (something like id) of a process ```cpp int mpi, rank; mpi = MPI_Init(&argc, &argv); //important to init first mpi = MPI_Comm_rank(MPI_COMM_WORLD, &rank); printf("Coming from rank/process %d\n", rank); ``` ```bash ┌──(aan㉿aan)-[~/HPPC] └─$ mpirun -np 1 helloworld Coming from rank/process 0 ``` ```bash ┌──(aan㉿aan)-[~/HPPC] └─$ mpirun -np 2 helloworld Coming from rank/process 0 Coming from rank/process 1 ``` # Chapter 6 (Sending & Receiving Messages) Messages sent must be using MPI Datatypes | MPI Datatype | C/C++ Datatype | | -------- | -------- | | MPI_CHAR | Char | | MPI_INT | INT | | MPI_FLOAT | Float | | MPI_DOUBLE | Double | Asynchronous >Sender send without knowing bila receiver dapat the message Synchronous > 1. You send you know when the receiver will receive the message > 2. The receiver also know when the sender send a message Blocking > Process is blocked until the operation has completed Non Blocking > Just proceed without waiting for the communication #### MPI_Send() & MPI_Recv() MPI_Send(data address, size of data, data type, rank/id of receiver, tag (can be anything, but must tally with MPI_Recv() method) MPI_Recv(data address, size of data, data type, sender rank/id, tag(can be anything but must be tally with MPI_Send() method) ```cpp #include <stdio.h> #include <mpi.h> int main(int argc, char** argv){ MPI_Init(&argc, &argv); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); int size; MPI_Comm_size(MPI_COMM_WORLD, &size); int data; if(rank == 0){ data = -1; MPI_Send(&data, 1, MPI_INT, 1, 100, MPI_COMM_WORLD); }else if (rank == 1){ MPI_Recv(&data, 1, MPI_INT, 0, 100, MPI_COMM_WORLD, MPI_STATUS_IGNORE); printf("Process %d received %d from Process 0", rank, data); } MPI_Finalize(); } ``` ```bash ┌──(aan㉿aan)-[~/HPPC] └─$ mpirun -np 2 helloworld Process 1 received -1 from Process 0 ``` #### Wildcarding So that you can make the receiver process receive data from any process, with any tag Example Scenario ![image](https://hackmd.io/_uploads/HJ9zyFDbll.png) ```cpp #include <stdio.h> #include <mpi.h> int main(int argc, char** argv){ MPI_Init(&argc, &argv); MPI_Status status; int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); int size; MPI_Comm_size(MPI_COMM_WORLD, &size); int data, number = 0; int target_rank = 3; if(rank < 3){ data = 10; printf("Process %d is sending %d to process 4\n", rank, data); MPI_Send(&data, 1, MPI_INT, 3, 10, MPI_COMM_WORLD ); }else if(rank == 3){ for(int i = 0; i < 3; i++){ MPI_Recv(&data, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); printf("Received %d from %d with the tag of %d\n", data, status.MPI_SOURCE, status.MPI_TAG); } } MPI_Finalize(); } ``` ```bash ┌──(aan㉿aan)-[~/HPPC] └─$ mpirun -np 4 helloworld3 Process 0 is sending 10 to process 4 Process 2 is sending 10 to process 4 Process 1 is sending 10 to process 4 Received 10 from 2 with the tag of 10 Received 10 from 1 with the tag of 10 Received 10 from 0 with the tag of 10 ``` #### Time Execution > Datatype must be double ```cpp #include <stdio.h> #include <mpi.h> #include <unistd.h> int main(int argc, char** argv) { double startTime, endTime; int rank; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); startTime = MPI_Wtime(); sleep(5 * rank); endTime = MPI_Wtime(); printf("Sleeping of process %d times taken %.2f\n", rank, endTime - startTime); fflush(stdout); MPI_Finalize(); return 0; } ``` ```bash ┌──(aan㉿aan)-[~/HPPC] └─$ mpirun -np 4 meow Sleeping of process 0 times taken 0.00 Sleeping of process 1 times taken 5.00 Sleeping of process 2 times taken 10.00 Sleeping of process 3 times taken 15.00 ``` Damn the rest im too lazy to read and code.