escript  Revision_
Esys_MPI.h
Go to the documentation of this file.
00001 
00002 /*****************************************************************************
00003 *
00004 * Copyright (c) 2003-2014 by University of Queensland
00005 * http://www.uq.edu.au
00006 *
00007 * Primary Business: Queensland, Australia
00008 * Licensed under the Open Software License version 3.0
00009 * http://www.opensource.org/licenses/osl-3.0.php
00010 *
00011 * Development until 2012 by Earth Systems Science Computational Center (ESSCC)
00012 * Development 2012-2013 by School of Earth Sciences
00013 * Development from 2014 by Centre for Geoscience Computing (GeoComp)
00014 *
00015 *****************************************************************************/
00016 
00017 
00018 #ifndef INC_ESYS_MPI
00019 #define INC_ESYS_MPI
00020 
00021 #include "system_dep.h"
00022 #include "types.h"
00023 
00024 #include <sstream>
00025 
00026 #ifdef ESYS_MPI
00027    #include "mpi_C.h"
00028 #else
00029    typedef int MPI_Comm;
00030    typedef int MPI_Request;
00031    typedef int MPI_Status;
00032    #define MPI_INT 6
00033    #define MPI_DOUBLE 11
00034    #define MPI_COMM_WORLD 91
00035 #endif
00036 
00037 typedef int Esys_MPI_rank;
00038 
00039 #define ESYS_MPI_TODO   { fprintf( stdout, "\nTODO : %s:%d\n", __FILE__, __LINE__); MPI_Finalize(); exit(1); }
00040 
00041 // Modding by 7 digit prime to avoid overflow
00042 #define ESYS_MPI_INC_COUNTER(V,I) {(V).msg_tag_counter=((V).msg_tag_counter+(I))%1010201;}
00043 #define ESYS_MPI_SET_COUNTER(V,I) {(V).msg_tag_counter=(I)%1010201;}
00044 
00045 /* Datatypes */
00046 
00048 struct Esys_MPIInfo {
00049   dim_t reference_counter;
00050   int size;
00051   Esys_MPI_rank rank;
00052   MPI_Comm comm;
00053   int msg_tag_counter;
00054 };
00055 
00056 typedef struct Esys_MPIInfo Esys_MPIInfo;
00057 
00058 /* Function prototypes */
00059 
00060 ESYSUTILS_DLL_API
00061 Esys_MPIInfo* Esys_MPIInfo_alloc( MPI_Comm comm );
00062 
00063 ESYSUTILS_DLL_API
00064 void          Esys_MPIInfo_free( Esys_MPIInfo* );
00065 
00066 ESYSUTILS_DLL_API
00067 Esys_MPIInfo *Esys_MPIInfo_getReference( Esys_MPIInfo* in );
00068 
00069 ESYSUTILS_DLL_API
00070 int           Esys_MPIInfo_initialized( void );
00071 
00072 ESYSUTILS_DLL_API
00073 index_t Esys_MPIInfo_mod(index_t n, index_t k);
00074 
00075 ESYSUTILS_DLL_API
00076 dim_t Esys_MPIInfo_setDistribution(Esys_MPIInfo* in ,index_t min_id,index_t max_id,index_t* distribution);
00077 
00078 ESYSUTILS_DLL_API
00079 void Esys_MPIInfo_Split( Esys_MPIInfo *mpi_info, dim_t n, dim_t* local_N,index_t* offset); 
00080 
00081 ESYSUTILS_DLL_API
00082 bool Esys_MPIInfo_noError( Esys_MPIInfo *mpi_info);
00083 
00084 namespace esysUtils {
00085 
00087 ESYSUTILS_DLL_API
00088 inline std::string appendRankToFileName(const std::string &fileName,
00089                                         int mpiSize, int mpiRank)
00090 {
00091     std::stringstream ss;
00092     ss << fileName;
00093     if (mpiSize > 1) {
00094         ss << '.';
00095         ss.fill('0');
00096         ss.width(4);
00097         ss << mpiRank;
00098     }
00099     std::string result(ss.str());
00100     return result;
00101 }
00102 
00103 /* has the have sub-communicators been created? */
00104 bool getSplitWorld();
00105 /* record that a sub-communicator has been created or used */
00106 void splitWorld();
00107 
00108 } // namespace esysUtils
00109 
00110 #endif /* INC_ESYS_MPI */
00111