Skip to content

Commit

Permalink
mpiwrap: make mpwiwrap.h/mpidummy.h includable from plain C
Browse files Browse the repository at this point in the history
  • Loading branch information
germasch committed Jun 6, 2019
1 parent 3e18040 commit d3e0fb7
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 18 deletions.
2 changes: 0 additions & 2 deletions source/adios2/ADIOSMPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#ifndef ADIOS2_ADIOSMPI_H_
#define ADIOS2_ADIOSMPI_H_

#include "adios2/ADIOSConfig.h"

#include "adios2/helper/mpiwrap.h"

#include <climits> //UXXX_MAX
Expand Down
26 changes: 15 additions & 11 deletions source/adios2/helper/mpidummy.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#ifndef ADIOS2_HELPER_MPIDUMMY_H_
#define ADIOS2_HELPER_MPIDUMMY_H_

#include <cstdint>
#include <cstdio>
#include "stdint.h"
#include "stdio.h"

#include "adios2/ADIOSConfig.h"

Expand All @@ -21,15 +21,15 @@
#include <mpi.h>
#else

using MPI_Comm = int;
using MPI_Status = std::uint64_t;
using MPI_Request = std::uint64_t;
using MPI_File = std::FILE *;
using MPI_Info = int;
using MPI_Datatype = int;
using MPI_Offset = long int;
using MPI_Fint = int;
using MPI_Op = int;
typedef int MPI_Comm;
typedef uint64_t MPI_Status;
typedef uint64_t MPI_Request;
typedef FILE *MPI_File;
typedef int MPI_Info;
typedef int MPI_Datatype;
typedef long int MPI_Offset;
typedef int MPI_Fint;
typedef int MPI_Op;

#define MPI_SUCCESS 0
#define MPI_ERR_BUFFER 1 /* Invalid buffer pointer */
Expand Down Expand Up @@ -101,8 +101,10 @@ namespace helper
namespace mpidummy
{
#else
#ifdef __cplusplus
extern "C" {
#endif
#endif

int MPI_Init(int *argc, char ***argv);
int MPI_Finalize();
Expand Down Expand Up @@ -177,7 +179,9 @@ int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count,
} // end namespace helper
} // end namespace adios
#else
#ifdef __cplusplus
} // end extern "C"
#endif
#endif

#endif /* ADIOS2_MPIDUMMY_H_ */
1 change: 1 addition & 0 deletions source/adios2/helper/mpiwrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#include "mpiwrap.h"
#include "mpidummy.h"

static inline bool SMPI_Available()
{
Expand Down
56 changes: 51 additions & 5 deletions source/adios2/helper/mpiwrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,61 @@
#ifndef ADIOS2_HELPER_MPIWRAP_H_
#define ADIOS2_HELPER_MPIWRAP_H_

// Overview of the MPI wrapping:
// =============================
//
// Including this header provides a unified way of dealing with the
// building against an actual MPI library (ADIOS2_HAVE_MPI) vs using
// a dummy implementation, and also deals with running serially
// when built against MPI, but not calling MPI_Init
//
// MPI types / constants
// ---------------------
//
// If ADIOS2_HAVE_MPI is defined, the actual MPI types (in particular MPI_Comm)
// from the real MPI are always used, even in the dummy implementations that are
// used when MPI hasn't been initialized.
// Otherwise, the definitions from mpidummy.h are used. These types are in the
// global namespace.
//
// MPI_* functions
// -------------
//
// The usual MPI functions are always defined in the global namespace (extern
// "C"). If ADIOS2_HAVE_MPI is defined, the declarations come from mpi.h.
// Otherwise, these functions are declared in mpidummy.h, also extern "C".
//
// If ADIOS2_HAVE_MPI is defined, the declarations in mpidummy.h are put into
// adios2::helper::mpidummy in order to not interfere with the extern "C" ones,
// but this way they are still available to use in the SMPI_* wrappers
//
// SMPI_* wrappers
// ---------------
// The SMPI wrappers provide a way to write code that works in all three of the
// following cases:
// - If ADIOS2_HAVE_MPI is undefined, these wrappers call the corresponding
// extern "C" MPI functions, which in this case are the mpidummy
// implementations.
// - If ADIOS2_HAVE_MPI is defined, and MPI has been initialized, these wrappers
// call the corresponding extern "C" MPI functions, which in this case are the
// real MPI implementations.
// - If ADIOS2_HAVE_MPI is defined, and MPI has not been initialized, these
// wrappers call the corresponding adios2::helper::mpidummy MPI functions,
// which are serial only but don't require the real MPI to be initialized.

#include "adios2/ADIOSConfig.h"

// Get either the real MPI or mpidummy into the global namespace
#ifdef ADIOS2_HAVE_MPI
#include <mpi.h>
#else
#include "mpidummy.h"
#endif

// SMPI_* work just as the original MPI_* functions, but will also
// work if MPI_Init has not been called, as long asssuming the communicator is a
// single-proc communicator, by falling back to mpidummy in that case

#ifdef __cplusplus
extern "C" {
#endif

int SMPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm);
int SMPI_Comm_free(MPI_Comm *newcomm);
int SMPI_Comm_rank(MPI_Comm comm, int *rank);
Expand All @@ -36,6 +79,9 @@ int SMPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype,
MPI_Datatype recvtype, int root, MPI_Comm comm);
int SMPI_Reduce(const void *sendbuf, void *recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm);
}

#ifdef __cplusplus
}
#endif

#endif /* ADIOS2_HELPER_MPIWRAP_H_ */

0 comments on commit d3e0fb7

Please sign in to comment.