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.