---
# System prepended metadata

title: Chapter 5 (Basic MPI)

---

# 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.

