Hybrid MPI/OpenMP Hello World in C

Writing a simple C Hybrid MPI/OpenMP program that will say hello from each thread/process combination

C Hybrid MPI/OpenMP Hello World

MPI is a powerful tool to have in the HPC world, and combining it with OpenMP gives greater performance and resource felxibility

In this program we first initialise MPI to use threadding, then we initialise MPI.

Next, for each MPI process we create 4 OpenMP threads

Now we print out the MPI process number and the OpenMP thread number

Now we clean things up and exit

I used Intel oneAPI C compiler and HPC libraries to build and run this program, It is designed to only use 2 MPI processes and 4 OpenMP threads per MPI process, giving a total of 8 OpenMP threads. You can edit your code to make either be higher or lower to match your hardware.

This is the Makefile I used:

LFLAGS=-lm -fopenmp
CFLAGS=-O3 -ipo
CC=mpiicx

SRCS=$(wildcard *.c)
PROGS = $(patsubst %.c,%,$(SRCS))

all: $(PROGS)

%: %.c
	$(CC) $(CFLAGS) -o $@ $(LFLAGS)

clean: 
	rm -f $(PROGS)

.PHONY: all
	

hybrid-hello.c

	
// Hybrid MPI/OpenMP hello world program
#include <mpi.h>
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int provided;

// Tell the program we are going to use hybrid MPI/OpenMP
    MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
    if (provided < MPI_THREAD_FUNNELED) {
        fprintf(stderr, "The MPI implementation does not support the required level of threading.\n");
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

// Initialise MPI
    int world_size, world_rank;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

// Ensure that there are exactly 2 MPI processes
    if (world_size != 2) {
        fprintf(stderr, "This application requires exactly 2 MPI processes.\n");
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

// 
    double start_time, end_time;
    if (world_rank == 0) {
        start_time = MPI_Wtime();
    }

// For this example, use 4 OpenMP threads per MPI processvi	
    #pragma omp parallel num_threads(4)
    {
        int thread_id = omp_get_thread_num();
// Print out the current thread ID and Process ID
        printf("Hello World from OpenMP thread %d on MPI process %d\n", thread_id, world_rank);
    }

// Dont really need timing code, but its a good habbit to put it in all MPI programs
    if (world_rank == 0) {
        end_time = MPI_Wtime();
        printf("Execution Time: %f seconds\n", end_time - start_time);
    }

    MPI_Finalize();
    return 0;
}
	

runtime output

	
me@pi:~/c/hybrid-hello$ mpirun -np 2 ./hybrid-hello
Hello World from OpenMP thread 2 on MPI process 1
Hello World from OpenMP thread 0 on MPI process 1
Hello World from OpenMP thread 1 on MPI process 1
Hello World from OpenMP thread 0 on MPI process 0
Hello World from OpenMP thread 3 on MPI process 1
Hello World from OpenMP thread 2 on MPI process 0
Hello World from OpenMP thread 1 on MPI process 0
Hello World from OpenMP thread 3 on MPI process 0
Execution Time: 0.000504 seconds
me@pi:~/c/hybrid-hello$
	

Mission Accomplished

And there we have it, MPI and OpenMP living to gether in perfect harmony.