# README - MPI and OpenMP (Naive n-Body Example)

## Description

This sample is a simple particle simulation in C++ 14 using MPI with OpenMP. The code is explicitly not optmized for better understanding. The idea is to run one MPI process per compute node. Within a node, the simulation is parallelized using OpenMP.

This code sample demonstates:
 * How to setup MPI for Multithreading (OpenMP)
 * **collective communication**, i.e. `MPI_Bcast`, `MPI_Allgather`
 * How to use MPI-Datatypes to **send and receive non-contiguous structured data** directly, avoiding send and receive buffer packing and unpacking.
 
 The code sample is structures as followed:
 
  * `Configuration.hpp`: Configuration structure, command-line parsing.
  * `MpiComm`: Wrapper class for an MPI_Comm object
  * `MpiEnvironment`: Wrapper class for the MPI Environment
  * `main.cpp`: The main program.
  * `MpiTypes.hpp`: Code for initialization of custom MPI-Datatypes.
  * `Particle.hpp`: Particle structure.
  * `Vec3.hpp`: 3D-Vector structure, arithmetrical operators
  * `gsl/*`: Guideline Support Library [C++ Core Guidelines](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines), is a utility library. (https://github.com/Microsoft/GSL)
  
## Release Date

2016-07-27


## Version History

 * 2016-07-27 Initial Release on PRACE CodeVault repository


## Contributors

 * Thomas Steinreiter - [thomas.steinreiter@risc-software.at](mailto:thomas.steinreiter@risc-software.at)


## Copyright

This code is available under Apache License, Version 2.0 - see also the license file in the CodeVault root directory. The GSL library is available under MIT.


## Languages

This sample is written in C++ 14.


## Parallelisation

This sample uses MPI-3 and OpenMP-2 for parallelisation.


## Level of the code sample complexity

Intermediate / Advanced


## Compiling

Follow the compilation instructions given in the main directory of the kernel samples directory (`/hpc_kernel_samples/README.md`).

## Running

To run the program, use something similar to

    mpiexec -n [nprocs] ./4_nbody_naive__openmp -i [ni] -p [np]

either on the command line or in your batch script, where `ni` specifies the number of iterations and `np` specify the number of particles. If missing, the value `1000` is used.


### Command line arguments

 * `-i [iterations]`: specify the number of iterations, which are simulated
 * `-p [particles]`: specify the number of particles in the simulation
 
### Example
 
If you run
	
	mpiexec -n 4 ./4_nbody_naive__openmp -p 1000 -i 1000

the output should look similar to

	Initialization done:
      0X:  0.08027579
      1X:   -0.393644
      2X:   0.8064011
      3X:    0.124666
      4X:  0.04687599
      5X:  -0.6595199
      6X:  -0.5110789
      7X:   0.3267961
      8X:  -0.5686927
      9X:  -0.2350721
	End Simulation
      0X:  0.08116845
      1X:  -0.4051199
      2X:   0.7923328
      3X:    0.122736
      4X:  0.04018182
      5X:  -0.6666988
      6X:  -0.5222901
      7X:   0.3513719
      8X:  -0.5790479
      9X:  -0.2378581
