Hybrid MPI and OpenMP example

Posted on Tue 28 October 2014 by Pavlo Khmel

Install compiler

sudo yum install gcc gcc-gfortran gcc-c++

Compile and install MPICH

wget http://www.mpich.org/static/downloads/3.1.3/mpich-3.1.3.tar.gz
tar xzf mpich-3.1.3.tar.gz
mkdir mpich_install
cd mpich-3.1.3
./configure --prefix=/home/pavlo/mpich_install/
make
make install

BASH environment temporary

export PATH=$HOME/mpich_install/bin:$PATH
export LD_LIBRARY_PATH=$HOME/mpich_install/lib:${LD_LIBRARY_PATH}
export MANPATH=$HOME/mpich_install/share/man:${MANPATH}

BASH environment permanent

echo 'export PATH=$HOME/mpich_install/bin:$PATH' >> ~/.bash_profile
echo 'export LD_LIBRARY_PATH=$HOME/mpich_install/lib:${LD_LIBRARY_PATH}' >> ~/.bash_profile
echo 'export MANPATH=$HOME/mpich_install/share/man:${MANPATH}' >> ~/.bash_profile

Get compiler info

mpicc -compile_info
gcc -I/home/pavlo/mpich_install/include -L/home/pavlo/mpich_install/lib -Wl,-rpath -Wl,/home/pavlo/mpich_install/lib -Wl,--enable-new-dtags -lmpi

Compile hello_hybrid application

mpicc -o hello_hybrid hello_hybrid.c -fopenmp

Run application

$ mpiexec ./hello_hybrid
Hello from thread 03 out of 4 from process 0 out of 1 on node1 calculated in 32.17 seconds
Hello from thread 00 out of 4 from process 0 out of 1 on node1 calculated in 32.17 seconds
Hello from thread 01 out of 4 from process 0 out of 1 on node1 calculated in 32.17 seconds
Hello from thread 02 out of 4 from process 0 out of 1 on node1 calculated in 32.18 seconds

Source code hello_hybrid.c

#include <stdio.h>;
#include "mpi.h";
#include <omp.h>;
#include <time.h>;

int main(int argc, char *argv[]) {
  int numprocs, rank, namelen;
  char processor_name[MPI_MAX_PROCESSOR_NAME];
  int iam = 0, np = 1;
  // cpu busy
  double start, end;
  double runTime;
  start = omp_get_wtime();
  int num = 1,primes = 0;
  int limit = 1000000;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Get_processor_name(processor_name, &namelen);

  #pragma omp parallel default(shared) private(iam, np)
  {
    for (num = 1; num <= limit; num++) {
        int i = 2;
        while(i <= num) {
            if(num % i == 0)
                break;
            i++;
        }
        if(i == num)
            primes++;
          }

        end = omp_get_wtime();
        runTime = end - start;
        np = omp_get_num_threads();
        iam = omp_get_thread_num();
        printf("Hello from thread %.2d out of %d from process %d out of %d on %s calculated in %.4g secondsn",
           iam, np, rank, numprocs, processor_name, runTime);
  }

  MPI_Finalize();
}

Links:
http://docs.rcc\<.uchicago.edu/software/environments/hybrid-mpi-openmp/README.html
http://stackoverflow.com/questions/9244481/how-to-get-100-cpu-usage-from-a-c-program