MPQC 3.0.0-alpha
Loading...
Searching...
No Matches
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
18namespace mpqc {
19namespace 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
42 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
Contains new MPQC code since version 3.
Definition integralenginepool.hpp:37

Generated at Wed Sep 25 2024 02:45:30 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.12.0.