Using MPI With C

Setup and “Hello, World”#

Begin by logging into the cluster and logging in to a compile node. This can be done by loading the Alpine scheduler and using the command:

acompile

Next we must load MPI into our environment. Begin by loading in your choice of C++ compiler and its corresponding MPI library. Use the following commands if using the GNU C++ compiler:

GNU C++ Compiler moduleloadgcc moduleloadopenmpi Intel C/C++ Compiler moduleloadintel moduleloadimpi

This should prepare your environment with all the necessary tools to compile and run your MPI code. Let’s now begin to construct our C++ file. In this tutorial, we will name our code file: hello_world_mpi.cpp

Open hello_world_mpi.cpp and begin by including the C standard library <stdio.h> and the MPI library <mpi.h> , and by constructing the main function of the C++ code:

#include<stdio.h> #include<mpi.h> intmain(intargc,char**argv){ return0; }

Now let’s set up several MPI directives to parallelize our code. In this ‘Hello World’ tutorial we’ll be utilizing the following four directives:

MPI_Init()

The MPI_Init() function initializes the MPI environment. It takes in the addresses of the C++ command line arguments argc and argv.

MPI_Comm_size()

The MPI_Comm_size() function returns the total size of the environment via quantity of processes. The function takes in the MPI environment, and the memory address of an integer variable.

MPI_Comm_rank()

The MPI_Comm_rank() function returns the process ID of the processor that called the function. The function takes in the MPI environment, and the memory address of an integer variable.

MPI_Finalize()

The MPI_Finalize() function cleans up the MPI environment and ends MPI communications.

These four directives should be enough to get our parallel ‘Hello World’ program running. We will begin by creating two variables, process_Rank, and size_Of_Cluster, to store an identifier for each of the parallel processes and the number of processes running in the cluster, respectively. We will also implement the MPI_Init function which will initialize the MPI communicator:

#include<stdio.h> #include<mpi.h> intmain(intargc,char**argv){ intprocess_Rank,size_Of_Cluster; MPI_Init(&argc,&argv); return0; }

Let’s now obtain some information about our cluster of processors and print the information out for the user. We will use the functions MPI_Comm_size() and MPI_Comm_rank() to obtain the count of processes and the rank of a process, respectively:

#include<stdio.h> #include<mpi.h> intmain(intargc,char**argv){ intprocess_Rank,size_Of_Cluster; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&size_Of_Cluster); MPI_Comm_rank(MPI_COMM_WORLD,&process_Rank); printf("Hello World from process %d of %d\n",process_Rank,size_Of_Cluster); return0; }

Lastly let’s close the environment using MPI_Finalize():

#include<stdio.h> #include<mpi.h> intmain(intargc,char**argv){ intprocess_Rank,size_Of_Cluster; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&size_Of_Cluster); MPI_Comm_rank(MPI_COMM_WORLD,&process_Rank); printf("Hello World from process %d of %d\n",process_Rank,size_Of_Cluster); MPI_Finalize(); return0; }

Now the code is complete and ready to be compiled. Because this is an MPI program, we have to use a specialized compiler. Be sure to use the correct command based on which compiler you have loaded.

Open MPI mpic++hello_world_mpi.cpp-ohello_world_mpi.exe Intel MPI mpiicchello_world_mpi.cpp-ohello_world_mpi.exe

This will produce an executable we can pass to the cluster as a job. In order to execute MPI compiled code, a special command must be used:

mpirun-np4./hello_world_mpi.exe

The flag -np specifies the number of processors that are to be utilized in execution of the program.

In your job script, load the same compiler and OpenMPI choices you used above to compile the program, and run the job with Slurm to execute the application. Your job script should look something like this:

Open MPI #!/bin/bash #SBATCH -N 1 #SBATCH --ntasks 4 #SBATCH --job-name parallel_hello #SBATCH --partition atesting #SBATCH --qos testing #SBATCH --constraint ib #SBATCH --time 00:01:00 #SBATCH --output parallel_hello_world.out modulepurge moduleloadgcc moduleloadopenmpi mpirun-np4./hello_world_mpi.exe Intel MPI #!/bin/bash #SBATCH -N 1 #SBATCH --ntasks 4 #SBATCH --job-name parallel_hello #SBATCH --partition atesting #SBATCH --qos testing #SBATCH --constraint ib #SBATCH --time 00:01:00 #SBATCH --output parallel_hello_world.out modulepurge moduleloadintel moduleloadimpi mpirun-np4./hello_world_mpi.exe

Note

On Alpine, there are at most 64 cores per node. For applications that require more than 64 processes, you will need to request multiple nodes in your job. Our output file should look something like this:

HelloWorldfromprocess3of4 HelloWorldfromprocess2of4 HelloWorldfromprocess1of4 HelloWorldfromprocess0of4

Source: Dartmouth College Intro to MPI Guide

Từ khóa » Mpi.h C++