MPQC  3.0.0-alpha
base.hpp
1 #ifndef MPQC_MPI_BASE_HPP
2 #define MPQC_MPI_BASE_HPP
3 
4 #include "mpqc_config.h"
5 
6 #ifdef HAVE_MPI
7 #define OMPI_SKIP_MPICXX
8 #define MPICH_SKIP_MPICXX
9 #include <mpi.h>
10 #endif
11 
12 #include "mpqc/utility/mutex.hpp"
13 
14 #include <stdio.h>
15 #include <stdexcept>
16 #include <boost/thread.hpp>
17 
18 namespace mpqc {
19 namespace MPI {
20 
23 
24  void initialize(int thread_level);
25  void finalize();
26  std::string get_processor_name();
27 
28  // MPI stubs
29 #ifndef HAVE_MPI
30 
31  inline void initialize(int thread_level) {}
32  inline void finalize() {}
33  inline std::string get_processor_name() { return "localhost"; }
34 
35 #endif // HAVE_MPI
36 
37 #ifdef HAVE_MPI
38 
39 #ifndef DOXYGEN
40  struct threadsafe : boost::noncopyable {
43  threadsafe() {
44  locked_ = false;
45  int thread = MPI_THREAD_SINGLE;
46  MPI_Query_thread(&thread);
47  if (thread != MPI_THREAD_MULTIPLE) {
48  mutex::global::lock();
49  locked_ = true;
50  }
51  }
52  ~threadsafe() {
53  if (locked_) mutex::global::unlock();
54  }
55  private:
56  bool locked_;
57  };
58 #define MPQC_MPI_THREADSAFE threadsafe _threadsafe;
59 #endif // DOXYGEN
60 
61  template<typename T>
62  MPI_Datatype type();
63  // {
64  // BOOST_STATIC_ASSERT_MSG(false, "MPI Type mapping is not implemented");
65  // }
66 
67 #define MPQC_MPI_TYPE(T, MPI_DATATYPE) \
68  template<> inline MPI_Datatype type<T>() { return MPI_DATATYPE; }
69 
70  MPQC_MPI_TYPE(int, MPI_INT)
71  MPQC_MPI_TYPE(double, MPI_DOUBLE)
72 
73 #undef MPQC_MPI_TYPE
74 
75  inline void initialize(int thread_level) {
76  int initialized = 0;
77  MPI_Initialized(&initialized);
78  if (!initialized) {
79  int argc = 0;
80  char **argv = NULL;
81  int thread;
82  MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &thread);
83  }
84  int thread = MPI_THREAD_SINGLE;
85  MPI_Query_thread(&thread);
86  if (thread < MPI_THREAD_SERIALIZED) {
87  throw std::runtime_error("thread < MPI_THREAD_SERIALIZED");
88  }
89  }
90 
91  inline void finalize() {
92  MPI_Finalize();
93  }
94 
95  inline std::string get_processor_name() {
96  char name[MPI_MAX_PROCESSOR_NAME];
97  int len;
98  MPI_Get_processor_name(name, &len);
99  return std::string(name, len);
100  }
101 
102  inline MPI_Status wait(MPI_Request request, size_t us = 0) {
103  MPQC_MPI_THREADSAFE {
104  MPI_Status status;
105  if (!us) {
106  MPI_Wait(&request, &status);
107  return status;
108  }
109  while (true) {
110  int flag = 0;
111  MPI_Test(&request, &flag, &status);
112  if (flag) return status;
113  boost::this_thread::sleep(boost::posix_time::microseconds(us));
114  }
115  }
116  }
117 
118 #endif // HAVE_MPI
119 
121 
122 }
123 }
124 
125 #endif // MPQC_MPI_BASE_HPP
mpqc
Contains new MPQC code since version 3.
Definition: integralenginepool.hpp:37

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.