00001 #ifndef MPI_HELPER_H 00002 #define MPI_HELPER_H 00003 00004 //-------------------------------------------------------------------- 00005 // 00006 // This file is part of PEACE. 00007 // 00008 // PEACE is free software: you can redistribute it and/or modify it 00009 // under the terms of the GNU General Public License as published by 00010 // the Free Software Foundation, either version 3 of the License, or 00011 // (at your option) any later version. 00012 // 00013 // PEACE is distributed in the hope that it will be useful, but 00014 // WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU General Public License 00019 // along with PEACE. If not, see <http://www.gnu.org/licenses/>. 00020 // 00021 // Miami University makes no representations or warranties about the 00022 // suitability of the software, either express or implied, including 00023 // but not limited to the implied warranties of merchantability, 00024 // fitness for a particular purpose, or non-infringement. Miami 00025 // University shall not be liable for any damages suffered by licensee 00026 // as a result of using, result of using, modifying or distributing 00027 // this software or its derivatives. 00028 // 00029 // By using or copying this Software, Licensee agrees to abide by the 00030 // intellectual property laws, and all other applicable laws of the 00031 // U.S., and the terms of GNU General Public License (version 3). 00032 // 00033 // Authors: Dhananjai M. Rao raodm@muohio.edu 00034 // 00035 //--------------------------------------------------------------------- 00036 00037 /** \file MPIHelper.h 00038 00039 \brief File and macros to enable conditional compilation of MPI 00040 code so that PEACE can be built with and without MPI. 00041 00042 This header file has been introduced to permit PEACE to compile 00043 with and without the presence of MPI. The code is designed in such 00044 a way to enable the use of MPI without hurting the readability and 00045 development of PEACE. 00046 */ 00047 #ifndef _WINDOWS 00048 #include "config.h" 00049 #endif 00050 00051 #include "Utilities.h" 00052 00053 #ifdef HAVE_LIBMPI 00054 00055 // We have MPI. In this case the standard/default operation of the 00056 // system is good to go. 00057 #include <mpi.h> 00058 00059 #endif 00060 00061 /** \def MPI_GET_RANK 00062 00063 \brief A simple, convenience macro to conditionally call 00064 MPI::COMM_WORLD.Get_rank() 00065 00066 <p>This macro provides a convenient wrapper around MPI's 00067 MPI::COMM_WORD.Get_rank() method to conditionally use it. If MPI 00068 is available/enabled, this macro reduces to calling the actual 00069 Get_rank() method. However, if MPI is not available, this macro 00070 reduces to the constant 0 (one) making it appear as if there is 00071 only one process to work with. </p> 00072 00073 This macro can be used as shown below: 00074 00075 \code 00076 00077 #include "MPIHelper.h" 00078 00079 void someMethod() { 00080 // ... some code goes here .. 00081 int myRank = MPI_GET_RANK(); 00082 // ... more code goes here .. 00083 } 00084 00085 \endcode 00086 */ 00087 #ifdef HAVE_LIBMPI 00088 // We have MPI enabled 00089 #define MPI_GET_RANK() MPI::COMM_WORLD.Get_rank() 00090 #else 00091 // We don't have MPI 00092 #define MPI_GET_RANK() 0 00093 #endif 00094 00095 /** \def MPI_GET_SIZE 00096 00097 \brief A simple, convenience macro to conditionally call 00098 MPI::COMM_WORLD.Get_size() 00099 00100 <p>This macro provides a convenient wrapper around MPI's 00101 MPI::COMM_WORD.Get_size() method to conditionally use it. If MPI 00102 is available/enabled, this macro reduces to calling the actual 00103 Get_size() method. However, if MPI is not available, this macro 00104 reduces to the constant 1 (one) making it appear as if there is 00105 only one process to work with. </p> 00106 00107 This macro can be used as shown below: 00108 00109 \code 00110 00111 #include "MPIHelper.h" 00112 00113 void someMethod() { 00114 // ... some code goes here .. 00115 int WorkerCount = MPI_GET_SIZE(); 00116 // ... more code goes here .. 00117 } 00118 00119 \endcode 00120 */ 00121 #ifdef HAVE_LIBMPI 00122 // We have MPI enabled 00123 #define MPI_GET_SIZE() MPI::COMM_WORLD.Get_size() 00124 #else 00125 // We don't have MPI 00126 #define MPI_GET_SIZE() 1 00127 #endif 00128 00129 #ifndef HAVE_LIBMPI 00130 /** \def MPI_ANY_SOURCE 00131 00132 \brief If MPI is not available, this macro defines a dummy 00133 MPI_ANY_SOURCE. 00134 */ 00135 #define MPI_ANY_SOURCE -1 00136 #endif 00137 00138 /** \def MPI_STATUS 00139 00140 \brief A simple, convenience macro to conditionally provide a 00141 suitable definition for MPI::Status data structure depending on 00142 whether MPI is available (or not). 00143 00144 <p>This macro provides a convenient mechanism to work with 00145 MPI::Status data structure. If MPI is available, then it defaults 00146 to MPI::Status. On the other hand, if MPI is disabled then this 00147 macro provides a suitable definition so that the core code base 00148 does not get cluttered with unnecessary logic.</p> 00149 00150 This macro can be used as shown below: 00151 00152 \code 00153 00154 #include "MPIHelper.h" 00155 00156 void someMethod() { 00157 // ... some code goes here .. 00158 MPI_STATUS msgInfo; 00159 MPI_PROBE(sourceRank, REPOPULATE_REQUEST, msgInfo); 00160 // ... more code goes here .. 00161 } 00162 00163 \endcode 00164 */ 00165 #ifdef HAVE_LIBMPI 00166 #define MPI_STATUS MPI::Status 00167 #else 00168 // We don't have MPI. So provide a suitable definition for MPI_Status 00169 class MPI_STATUS { 00170 public: 00171 inline int Get_source() const { return 0; } 00172 inline int Get_count(const int UNREFERENCED_PARAMETER(type) = 0) const { return 0; } 00173 inline int Get_tag() const { return 0; } 00174 }; 00175 #endif 00176 00177 /** \def MPI_TYPE_INT 00178 00179 \brief Macro to map MPI_TYPE_INT to MPI::INT (if MPI is enabled) 00180 or 0 if MPI is unavailable. 00181 00182 <p>This macro provides a convenient, conditionally defined macro 00183 to refer to MPI::INT enumerated constant. If MPI is available, 00184 then MPI_TYPE_INT defaults to MPI::INT. On the other hand, if MPI 00185 is disabled then this macro simply reduces to 0.</p> 00186 00187 This macro can be used as shown below: 00188 00189 \code 00190 00191 #include "MPIHelper.h" 00192 00193 void someMethod() { 00194 // ... some code goes here .. 00195 MPI_STATUS msgInfo; 00196 MPI_PROBE(sourceRank, REPOPULATE_REQUEST, msgInfo); 00197 const int dataSize = msgInfo.Get_count(MPI_TYPE_INT); 00198 // ... more code goes here .. 00199 } 00200 \endcode 00201 */ 00202 #ifdef HAVE_LIBMPI 00203 #define MPI_TYPE_INT MPI::INT 00204 #else 00205 // MPI is not available 00206 #define MPI_TYPE_INT 0 00207 #endif 00208 00209 /** \def MPI_TYPE_CHAR 00210 00211 \brief Macro to map MPI_TYPE_CHAR to MPI::CHAR (if MPI is enabled) 00212 or 0 if MPI is unavailable. 00213 00214 <p>This macro provides a convenient, conditionally defined macro 00215 to refer to MPI::CHAR enumerated constant. If MPI is available, 00216 then MPI_TYPE_CHAR defaults to MPI::CHAR. On the other hand, if 00217 MPI is disabled then this macro simply reduces to 0.</p> 00218 00219 This macro can be used as shown below: 00220 00221 \code 00222 00223 #include "MPIHelper.h" 00224 00225 void someMethod() { 00226 // ... some code goes here .. 00227 MPI_STATUS msgInfo; 00228 MPI_PROBE(sourceRank, REPOPULATE_REQUEST, msgInfo); 00229 const int dataSize = msgInfo.Get_count(MPI_TYPE_CHAR); 00230 // ... more code goes here .. 00231 } 00232 \endcode 00233 */ 00234 #ifdef HAVE_LIBMPI 00235 #define MPI_TYPE_CHAR MPI::CHAR 00236 #else 00237 // MPI is not available 00238 #define MPI_TYPE_CHAR 0 00239 #endif 00240 00241 /** \def MPI_INIT 00242 00243 \brief Macro to map MPI_INIT to MPI::Init (if MPI is enabled) or 00244 an empty method call if MPI is unavailable. 00245 00246 <p>This macro provides a convenient, conditionally defined macro 00247 to refer to MPI::Init method. If MPI is available, then MPI_INIT 00248 defaults to MPI::Init. On the other hand, if MPI is disabled then 00249 this macro simply reduces to a blank method.</p> 00250 00251 This macro can be used as shown below: 00252 00253 \code 00254 00255 #include "MPIHelper.h" 00256 00257 int main(int argc, char *argv[]) { 00258 // ... some code goes here .. 00259 MPI_INIT(argc, argv); 00260 // ... more code goes here .. 00261 } 00262 \endcode 00263 */ 00264 #ifdef HAVE_LIBMPI 00265 #define MPI_INIT(argc, argv) MPI::Init(argc, argv) 00266 #else 00267 // MPI is not available 00268 #define MPI_INIT(argc, argv) 00269 #endif 00270 00271 /** \def MPI_FINALIZE 00272 00273 \brief Macro to map MPI_FINALIZE to MPI::Finalize (if MPI is 00274 enabled) or an empty method call if MPI is unavailable. 00275 00276 <p>This macro provides a convenient, conditionally defined macro 00277 to refer to MPI::Finalize method. If MPI is available, then 00278 MPI_FINALIZE defaults to MPI::Init. On the other hand, if MPI is 00279 disabled then this macro simply reduces to a blank method.</p> 00280 00281 This macro can be used as shown below: 00282 00283 \code 00284 00285 #include "MPIHelper.h" 00286 00287 int main(int argc, char *argv[]) { 00288 // ... some code goes here .. 00289 MPI_INIT(argc, argv); 00290 // ... more code goes here .. 00291 } 00292 \endcode 00293 */ 00294 #ifdef HAVE_LIBMPI 00295 #define MPI_FINALIZE() MPI::Finalize() 00296 #else 00297 // MPI is not available 00298 #define MPI_FINALIZE() 00299 #endif 00300 00301 /** \def MPI_WTIME 00302 00303 \brief Macro to map MPI_WTIME to MPI::Wtime (if MPI is enabled) or 00304 to a suitable OS-independent implementation for Wtime. 00305 00306 <p>This macro provides a convenient, conditionally defined macro 00307 to refer to MPI::Wtime method. If MPI is available, then MPI_WTIME 00308 defaults to MPI::Wtime. On the other hand, if MPI is disabled 00309 then this macro simply reduces to a suitable OS-independent method 00310 call.</p> 00311 00312 This macro can be used as shown below: 00313 00314 \code 00315 00316 #include "MPIHelper.h" 00317 00318 int main(int argc, char *argv[]) { 00319 // ... some code goes here .. 00320 const double startTime = MPI::Wtime(); 00321 // ... more code goes here .. 00322 const double elapsedTime = (MPI::Wtime() - startTime) * 1000.0; 00323 } 00324 \endcode 00325 */ 00326 #ifdef HAVE_LIBMPI 00327 #define MPI_WTIME MPI::Wtime 00328 #else 00329 // MPI is not available 00330 extern double MPI_WTIME(); 00331 #endif 00332 00333 /** \def MPI_CODE 00334 00335 \brief Macro to work around warnings about unused MPI variables or 00336 conditionally compile-out MPI code. 00337 00338 <p>This macro provides a convenient, conditionally defined macro 00339 to conditionally compile-out MPI related code when MPI is 00340 disabled.</p> 00341 00342 This macro can be used as shown below: 00343 00344 \code 00345 00346 #include "MPIHelper.h" 00347 00348 int main(int argc, char *argv[]) { 00349 // ... some code goes here .. 00350 MPI_CODE({ 00351 MPI_STATUS msgInfo; 00352 MPI_PROBE(sourceRank, REPOPULATE_REQUEST, msgInfo); 00353 }); 00354 // ... more code goes here .. 00355 } 00356 \endcode 00357 */ 00358 #ifdef HAVE_LIBMPI 00359 #define MPI_CODE(x) x 00360 #else 00361 // MPI is not available 00362 #define MPI_CODE(x) 00363 #endif 00364 00365 #endif