View on GitHub

CC

CC practice and cheat sheets

How to MPI

Ubuntu 20.04 -

sudo apt install mpich

#include <mpi.h>

void main( int argc, char** argv )
{
    MPI_Init( &argc, &argv );

    /* MPI Stuff */


    MPI_Finalize();
}

Data Types

MPI has their own stuff coz why not

MPI Datatype C Datatype
MPI_CHAR signed char
MPI_CHAR signed char
MPI_SIGNED_CHAR signed char
MPI_UNSIGNED_CHAR unsigned char
MPI_SHORT signed short
MPI_UNSIGNED_SHORT unsigned short
MPI_INT signed int
MPI_UNSIGNED unsigned int
MPI_LONG signed long
MPI_UNSIGNED_LONG unsigned long
MPI_FLOAT float
MPI_DOUBLE double
MPI_LONG_DOUBLE long double
MPI Blocking send
MPI_SEND(void *start, int count,MPI_DATATYPE datatype, int dest, int tag, MPI_COMM comm)

The message buffer is described by (start, count, datatype). dest is the rank of the target process in the defined communicator. tag is the message identification number.

MPI Blocking receive
MPI_RECV(void *start, int count, MPI_DATATYPE datatype, int source, int tag, MPI_COMM comm, MPI_STATUS *status)

Sample Program

Compile Instructions mpicc ./sample.c

Run with 4 hosts mpirun -n 4 ./a.out

#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>

int main(int argc, char *argv[])
{
    const int tag = 42; /* Message tag */
    int id, ntasks, source_id, dest_id, err, i;
    MPI_Status status;
    int msg[2]; /* Message array */

    err = MPI_Init(&argc, &argv); /* Initialize MPI */
    if (err != MPI_SUCCESS)
    {
        printf("MPI initialization failed!\n");
        exit(-1);
    }
    err = MPI_Comm_size(MPI_COMM_WORLD, &ntasks); /* Get nr of tasks */
    err = MPI_Comm_rank(MPI_COMM_WORLD, &id);     /* Get id of this process */
    if (ntasks < 2)
    {
        printf("You have to use at least 2 processors to run this program\n");
        MPI_Finalize(); /* Quit if there is only one processor */
        exit(MPI_SUCCESS);
    }
    if (id == 0)
    { /* Process 0 (the receiver) does this */
        for (i = 1; i < ntasks; i++)
        {
            err = MPI_Recv(msg, 2, MPI_INT, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD,
                           &status);       /* Receive a message */
            source_id = status.MPI_SOURCE; /* Get id of sender */
            printf("Received message %d %d from process %d\n", msg[0], msg[1],
                   source_id);
        }
    }
    else
    {                    /* Processes 1 to N-1 (the senders) do this */
        msg[0] = id;     /* Put own identifier in the message */
        msg[1] = ntasks; /* and total number of processes */
        dest_id = 0;     /* Destination address */
        err = MPI_Send(msg, 2, MPI_INT, dest_id, tag, MPI_COMM_WORLD);
    }

    err = MPI_Finalize(); /* Terminate MPI */
    if (id == 0)
        printf("Ready\n");
    exit(0);
    return 0;
}

Collective Operations

Sample Broadcase Program

Compile Instructions mpicc ./sample.c

Run with 4 hosts mpirun -n 4 ./a.out

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
void my_bcast(void *data, int count, MPI_Datatype datatype, int root, MPI_Comm communicator)
{
    int world_rank;
    MPI_Comm_rank(communicator, &world_rank);
    int world_size;
    MPI_Comm_size(communicator, &world_size);

    if (world_rank == root)
    {
        int i;
        for (i = 0; i < world_size; i++)
        {
            if (i != world_rank)
            {
                MPI_Send(data, count, datatype, i, 0, communicator);
            }
        }
    }
    else
    {
        MPI_Recv(data, count, datatype, root, 0, communicator, MPI_STATUS_IGNORE);
    }
}
int main(int argc, char **argv)
{
    MPI_Init(NULL, NULL);

    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

    int data;
    if (world_rank == 0)
    {
        data = 100;
        printf("Process 0 broadcasting data %d\n", data);
        my_bcast(&data, 1, MPI_INT, 0, MPI_COMM_WORLD);
    }
    else
    {
        my_bcast(&data, 1, MPI_INT, 0, MPI_COMM_WORLD);
        printf("Process %d received data %d from root process\n", world_rank, data);
    }

    MPI_Finalize();
}