LCOV - code coverage report
Current view: top level - tools - Communicator.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 81 103 78.6 %
Date: 2020-11-18 11:20:57 Functions: 26 32 81.2 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-2019 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.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       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 "Communicator.h"
      23             : #include "Exception.h"
      24             : #include <cstdlib>
      25             : 
      26             : using namespace std;
      27             : 
      28             : namespace PLMD {
      29             : 
      30        9742 : Communicator::Communicator()
      31             : #ifdef __PLUMED_HAS_MPI
      32        9742 :   : communicator(MPI_COMM_SELF)
      33             : #endif
      34             : {
      35        9742 : }
      36             : 
      37           0 : Communicator::Communicator(const Communicator&pc) {
      38           0 :   Set_comm(pc.communicator);
      39           0 : }
      40             : 
      41             : Communicator::Status Communicator::StatusIgnore;
      42             : 
      43           0 : Communicator& Communicator::operator=(const Communicator&pc) {
      44           0 :   if (this != &pc) {
      45           0 :     Set_comm(pc.communicator);
      46             :   }
      47           0 :   return *this;
      48             : }
      49             : 
      50     5904626 : int Communicator::Get_rank()const {
      51     5904626 :   int r=0;
      52             : #ifdef __PLUMED_HAS_MPI
      53     5904626 :   if(initialized()) MPI_Comm_rank(communicator,&r);
      54             : #endif
      55     5904626 :   return r;
      56             : }
      57             : 
      58           0 : Communicator& Communicator::Get_world() {
      59           0 :   static Communicator c;
      60             : #ifdef __PLUMED_HAS_MPI
      61           0 :   if(initialized()) c.communicator=MPI_COMM_WORLD;
      62             : #endif
      63           0 :   return c;
      64             : }
      65             : 
      66             : 
      67     2161827 : int Communicator::Get_size()const {
      68     2161827 :   int s=1;
      69             : #ifdef __PLUMED_HAS_MPI
      70     2161827 :   if(initialized()) MPI_Comm_size(communicator,&s);
      71             : #endif
      72     2161827 :   return s;
      73             : }
      74             : 
      75        1617 : void Communicator::Set_comm(MPI_Comm c) {
      76             : #ifdef __PLUMED_HAS_MPI
      77        1617 :   if(initialized()) {
      78        1317 :     if(communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
      79        1317 :     if(c!=MPI_COMM_SELF) MPI_Comm_dup(c,&communicator);
      80             :   }
      81             : #else
      82             :   (void) c;
      83             : #endif
      84        1617 : }
      85             : 
      86       25853 : Communicator::~Communicator() {
      87             : #ifdef __PLUMED_HAS_MPI
      88        9742 :   if(initialized() && communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
      89             : #endif
      90       16111 : }
      91             : 
      92         982 : void Communicator::Set_comm(void*val) {
      93             : #ifdef __PLUMED_HAS_MPI
      94         982 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
      95         982 :   if(val) Set_comm(*(MPI_Comm*)val);
      96             : #else
      97             :   (void) val;
      98             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
      99             : #endif
     100         982 : }
     101             : 
     102           0 : void Communicator::Set_fcomm(void*val) {
     103             : #ifdef __PLUMED_HAS_MPI
     104           0 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     105           0 :   if(val) {
     106           0 :     MPI_Comm comm=MPI_Comm_f2c(*(MPI_Fint*)val);
     107           0 :     Set_comm(comm);
     108             :   }
     109             : #else
     110             :   (void) val;
     111             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     112             : #endif
     113           0 : }
     114             : 
     115           0 : void Communicator::Abort(int errorcode) {
     116             : #ifdef __PLUMED_HAS_MPI
     117           0 :   if(initialized()) {
     118           0 :     MPI_Abort(communicator,errorcode);
     119             :   }
     120           0 :   std::exit(errorcode);
     121             : #else
     122             :   std::exit(errorcode);
     123             : #endif
     124             : }
     125             : 
     126     3952467 : void Communicator::Bcast(Data data,int root) {
     127             : #if defined(__PLUMED_HAS_MPI)
     128     3952467 :   if(initialized()) MPI_Bcast(data.pointer,data.size,data.type,root,communicator);
     129             : #else
     130             :   (void) data;
     131             :   (void) root;
     132             : #endif
     133     3952467 : }
     134             : 
     135     3911050 : void Communicator::Sum(Data data) {
     136             : #if defined(__PLUMED_HAS_MPI)
     137     3911050 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_SUM,communicator);
     138             : #else
     139             :   (void) data;
     140             : #endif
     141     3911050 : }
     142             : 
     143       14656 : Communicator::Request Communicator::Isend(ConstData data,int source,int tag) {
     144             :   Request req;
     145             : #ifdef __PLUMED_HAS_MPI
     146       14656 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     147       14656 :   void*s=const_cast<void*>((const void*)data.pointer);
     148       14656 :   MPI_Isend(s,data.size,data.type,source,tag,communicator,&req.r);
     149             : #else
     150             :   (void) data;
     151             :   (void) source;
     152             :   (void) tag;
     153             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     154             : #endif
     155       14656 :   return req;
     156             : }
     157             : 
     158        2270 : void Communicator::Allgatherv(ConstData in,Data out,const int*recvcounts,const int*displs) {
     159             : #if defined(__PLUMED_HAS_MPI)
     160        2270 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     161        2270 :   void*s=const_cast<void*>((const void*)in.pointer);
     162        2270 :   void*r=const_cast<void*>((const void*)out.pointer);
     163             :   int*rc=const_cast<int*>(recvcounts);
     164             :   int*di=const_cast<int*>(displs);
     165        2270 :   if(s==NULL)s=MPI_IN_PLACE;
     166        2270 :   MPI_Allgatherv(s,in.size,in.type,r,rc,di,out.type,communicator);
     167             : #else
     168             :   (void) in;
     169             :   (void) out;
     170             :   (void) recvcounts;
     171             :   (void) displs;
     172             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     173             : #endif
     174        2270 : }
     175             : 
     176         515 : void Communicator::Allgather(ConstData in,Data out) {
     177             : #if defined(__PLUMED_HAS_MPI)
     178         515 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     179         515 :   void*s=const_cast<void*>((const void*)in.pointer);
     180         515 :   void*r=const_cast<void*>((const void*)out.pointer);
     181         515 :   if(s==NULL)s=MPI_IN_PLACE;
     182         515 :   MPI_Allgather(s,in.size,in.type,r,out.size/Get_size(),out.type,communicator);
     183             : #else
     184             :   (void) in;
     185             :   (void) out;
     186             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     187             : #endif
     188         515 : }
     189             : 
     190       14656 : void Communicator::Recv(Data data,int source,int tag,Status&status) {
     191             : #ifdef __PLUMED_HAS_MPI
     192       14656 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     193       14656 :   if(&status==&StatusIgnore) MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,MPI_STATUS_IGNORE);
     194        7281 :   else                       MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,&status.s);
     195             : #else
     196             :   (void) data;
     197             :   (void) source;
     198             :   (void) tag;
     199             :   (void) status;
     200             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     201             : #endif
     202       14656 : }
     203             : 
     204             : 
     205             : 
     206             : 
     207             : 
     208     3908218 : void Communicator::Barrier()const {
     209             : #ifdef __PLUMED_HAS_MPI
     210     3908218 :   if(initialized()) MPI_Barrier(communicator);
     211             : #endif
     212     3908218 : }
     213             : 
     214        1146 : MPI_Comm & Communicator::Get_comm() {
     215        1146 :   return communicator;
     216             : }
     217             : 
     218    19905217 : bool Communicator::initialized() {
     219    19905217 :   int flag=false;
     220             : #if defined(__PLUMED_HAS_MPI)
     221    19905217 :   MPI_Initialized(&flag);
     222             : #endif
     223    19905217 :   if(flag) return true;
     224    11518055 :   else return false;
     225             : }
     226             : 
     227       14320 : void Communicator::Request::wait(Status&s) {
     228             : #ifdef __PLUMED_HAS_MPI
     229       14320 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     230       14320 :   if(&s==&StatusIgnore) MPI_Wait(&r,MPI_STATUS_IGNORE);
     231           1 :   else MPI_Wait(&r,&s.s);
     232             : #else
     233             :   (void) s;
     234             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     235             : #endif
     236       14320 : }
     237             : 
     238             : #ifdef __PLUMED_HAS_MPI
     239           0 : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_FLOAT;}
     240     3959999 : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_DOUBLE;}
     241       30980 : template<> MPI_Datatype Communicator::getMPIType<int>()   { return MPI_INT;}
     242         174 : template<> MPI_Datatype Communicator::getMPIType<char>()   { return MPI_CHAR;}
     243       10237 : template<> MPI_Datatype Communicator::getMPIType<unsigned>()   { return MPI_UNSIGNED;}
     244     3904290 : template<> MPI_Datatype Communicator::getMPIType<long unsigned>()   { return MPI_UNSIGNED_LONG;}
     245             : #else
     246             : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_Datatype();}
     247             : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_Datatype();}
     248             : template<> MPI_Datatype Communicator::getMPIType<int>() { return MPI_Datatype();}
     249             : template<> MPI_Datatype Communicator::getMPIType<char>() { return MPI_Datatype();}
     250             : template<> MPI_Datatype Communicator::getMPIType<unsigned>() { return MPI_Datatype();}
     251             : template<> MPI_Datatype Communicator::getMPIType<long unsigned>() { return MPI_Datatype();}
     252             : #endif
     253             : 
     254             : 
     255         310 : void Communicator::Split(int color,int key,Communicator&pc)const {
     256             : #ifdef __PLUMED_HAS_MPI
     257         310 :   MPI_Comm_split(communicator,color,key,&pc.communicator);
     258             : #else
     259             :   (void) color;
     260             :   (void) key;
     261             :   (void) pc;
     262             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     263             : #endif
     264         310 : }
     265             : 
     266        7281 : int Communicator::Status::Get_count(MPI_Datatype type)const {
     267             :   int i;
     268             : #ifdef __PLUMED_HAS_MPI
     269        7281 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     270        7281 :   MPI_Get_count(const_cast<MPI_Status*>(&s),type,&i);
     271             : #else
     272             :   i=0;
     273             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     274             : #endif
     275        7281 :   return i;
     276             : }
     277             : 
     278        4839 : }
     279             : 

Generated by: LCOV version 1.13