All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Communicator.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 The plumed team
3  (see the PEOPLE file at the root of the distribution for a list of names)
4 
5  See http://www.plumed-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
8 
9  plumed is free software: you can redistribute it and/or modify
10  it under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  plumed is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 #include <cstdlib>
23 #include "Communicator.h"
24 #include "Exception.h"
25 
26 using namespace std;
27 
28 namespace PLMD{
29 
30 Communicator::Communicator()
31 #ifdef __PLUMED_MPI
32 : communicator(MPI_COMM_SELF)
33 #endif
34 {
35 }
36 
37 Communicator::Communicator(const Communicator&pc){
38  Set_comm(pc.communicator);
39 }
40 
41 Communicator& Communicator::operator=(const Communicator&pc){
42  if (this != &pc){
43  Set_comm(pc.communicator);
44  }
45  return *this;
46 }
47 
48 int Communicator::Get_rank()const{
49  int r=0;
50 #ifdef __PLUMED_MPI
51  if(initialized()) MPI_Comm_rank(communicator,&r);
52 #endif
53  return r;
54 }
55 
56 Communicator& Communicator::Get_world(){
57  static Communicator c;
58 #ifdef __PLUMED_MPI
59  if(initialized()) c.communicator=MPI_COMM_WORLD;
60 #endif
61  return c;
62 }
63 
64 
65 int Communicator::Get_size()const{
66  int s=1;
67 #ifdef __PLUMED_MPI
68  if(initialized()) MPI_Comm_size(communicator,&s);
69 #endif
70  return s;
71 }
72 
73 void Communicator::Set_comm(MPI_Comm c){
74 #ifdef __PLUMED_MPI
75  if(initialized()){
76  if(communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
77  if(c!=MPI_COMM_SELF) MPI_Comm_dup(c,&communicator);
78  }
79 #else
80  (void) c;
81 #endif
82 }
83 
84 Communicator::~Communicator(){
85 #ifdef __PLUMED_MPI
86  if(initialized() && communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
87 #endif
88 }
89 
90 void Communicator::Set_comm(void*val){
91 #ifdef __PLUMED_MPI
92  plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
93  if(val) Set_comm(*(MPI_Comm*)val);
94 #else
95  (void) val;
96  plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
97 #endif
98 }
99 
100 void Communicator::Set_fcomm(void*val){
101 #ifdef __PLUMED_MPI
102  plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
103  if(val){
104  MPI_Comm comm=MPI_Comm_f2c(*(MPI_Fint*)val);
105  Set_comm(comm);
106  }
107 #else
108  (void) val;
109  plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
110 #endif
111 }
112 
113 void Communicator::Abort(int errorcode){
114 #ifdef __PLUMED_MPI
115  if(initialized()){
116  MPI_Abort(communicator,errorcode);
117  }
118  std::exit(errorcode);
119 #else
120  std::exit(errorcode);
121 #endif
122 }
123 
124 void Communicator::Barrier()const{
125 #ifdef __PLUMED_MPI
126  if(initialized()) MPI_Barrier(communicator);
127 #endif
128 }
129 
130 MPI_Comm & Communicator::Get_comm(){
131  return communicator;
132 }
133 
134 bool Communicator::initialized(){
135  int flag=false;
136 #if defined(__PLUMED_MPI)
137  MPI_Initialized(&flag);
138 #endif
139  if(flag) return true;
140  else return false;
141 }
142 
143 void Communicator::Request::wait(){
144 #ifdef __PLUMED_MPI
145  plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
146  MPI_Wait(&r,MPI_STATUS_IGNORE);
147 #else
148  plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
149 #endif
150 }
151 
152 void Communicator::Request::wait(Status&s){
153 #ifdef __PLUMED_MPI
154  plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
155  MPI_Wait(&r,&s.s);
156 #else
157  (void) s;
158  plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
159 #endif
160 }
161 
162 #ifdef __PLUMED_MPI
163 template<> MPI_Datatype Communicator::getMPIType<float>(){ return MPI_FLOAT;}
164 template<> MPI_Datatype Communicator::getMPIType<double>(){ return MPI_DOUBLE;}
165 template<> MPI_Datatype Communicator::getMPIType<int>() { return MPI_INT;}
166 template<> MPI_Datatype Communicator::getMPIType<char>() { return MPI_CHAR;}
167 template<> MPI_Datatype Communicator::getMPIType<unsigned>() { return MPI_UNSIGNED;}
168 template<> MPI_Datatype Communicator::getMPIType<long unsigned>() { return MPI_UNSIGNED_LONG;}
169 #endif
170 
171 
172 void Communicator::Split(int color,int key,Communicator&pc)const{
173 #ifdef __PLUMED_MPI
174  MPI_Comm_split(communicator,color,key,&pc.communicator);
175 #else
176  plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
177 #endif
178 }
179 
180 }
181 
Class containing wrappers to MPI.
Definition: Communicator.h:44
STL namespace.
Surrogate of MPI types when MPI library is not available.
Definition: Communicator.h:34
MPI_Comm communicator
Communicator.
Definition: Communicator.h:46