LCOV - code coverage report
Current view: top level - tools - Communicator.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 90 108 83.3 %
Date: 2021-11-18 15:22:58 Functions: 29 34 85.3 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-2020 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       11212 : Communicator::Communicator()
      31             : #ifdef __PLUMED_HAS_MPI
      32       11212 :   : communicator(MPI_COMM_SELF)
      33             : #endif
      34             : {
      35       11212 : }
      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     6055384 : int Communicator::Get_rank()const {
      51     6055384 :   int r=0;
      52             : #ifdef __PLUMED_HAS_MPI
      53     6055384 :   if(initialized()) MPI_Comm_rank(communicator,&r);
      54             : #endif
      55     6055384 :   return r;
      56             : }
      57             : 
      58     2228748 : int Communicator::Get_size()const {
      59     2228748 :   int s=1;
      60             : #ifdef __PLUMED_HAS_MPI
      61     2228748 :   if(initialized()) MPI_Comm_size(communicator,&s);
      62             : #endif
      63     2228748 :   return s;
      64             : }
      65             : 
      66        1850 : void Communicator::Set_comm(MPI_Comm c) {
      67             : #ifdef __PLUMED_HAS_MPI
      68        1850 :   if(initialized()) {
      69        1517 :     if(communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
      70        1517 :     if(c!=MPI_COMM_SELF) MPI_Comm_dup(c,&communicator);
      71             :   }
      72             : #else
      73             :   (void) c;
      74             : #endif
      75        1850 : }
      76             : 
      77       29762 : Communicator::~Communicator() {
      78             : #ifdef __PLUMED_HAS_MPI
      79       11212 :   if(initialized() && communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
      80             : #endif
      81       18550 : }
      82             : 
      83        1142 : void Communicator::Set_comm(void*val) {
      84             : #ifdef __PLUMED_HAS_MPI
      85        1142 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
      86        1142 :   if(val) Set_comm(*(MPI_Comm*)val);
      87             : #else
      88             :   (void) val;
      89             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
      90             : #endif
      91        1142 : }
      92             : 
      93           0 : void Communicator::Set_fcomm(void*val) {
      94             : #ifdef __PLUMED_HAS_MPI
      95           0 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
      96           0 :   if(val) {
      97           0 :     MPI_Comm comm=MPI_Comm_f2c(*(MPI_Fint*)val);
      98           0 :     Set_comm(comm);
      99             :   }
     100             : #else
     101             :   (void) val;
     102             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     103             : #endif
     104           0 : }
     105             : 
     106           0 : void Communicator::Abort(int errorcode) {
     107             : #ifdef __PLUMED_HAS_MPI
     108           0 :   if(initialized()) {
     109           0 :     MPI_Abort(communicator,errorcode);
     110             :   }
     111           0 :   std::exit(errorcode);
     112             : #else
     113             :   std::exit(errorcode);
     114             : #endif
     115             : }
     116             : 
     117     4103755 : void Communicator::Bcast(Data data,int root) {
     118             : #if defined(__PLUMED_HAS_MPI)
     119     4103755 :   if(initialized()) MPI_Bcast(data.pointer,data.size,data.type,root,communicator);
     120             : #else
     121             :   (void) data;
     122             :   (void) root;
     123             : #endif
     124     4103755 : }
     125             : 
     126     3928007 : void Communicator::Sum(Data data) {
     127             : #if defined(__PLUMED_HAS_MPI)
     128     3928007 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_SUM,communicator);
     129             : #else
     130             :   (void) data;
     131             : #endif
     132     3928007 : }
     133             : 
     134           3 : void Communicator::Prod(Data data) {
     135             : #if defined(__PLUMED_HAS_MPI)
     136           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_PROD,communicator);
     137             : #else
     138             :   (void) data;
     139             : #endif
     140           3 : }
     141             : 
     142           3 : void Communicator::Max(Data data) {
     143             : #if defined(__PLUMED_HAS_MPI)
     144           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MAX,communicator);
     145             : #else
     146             :   (void) data;
     147             : #endif
     148           3 : }
     149             : 
     150           3 : void Communicator::Min(Data data) {
     151             : #if defined(__PLUMED_HAS_MPI)
     152           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MIN,communicator);
     153             : #else
     154             :   (void) data;
     155             : #endif
     156           3 : }
     157             : 
     158       15206 : Communicator::Request Communicator::Isend(ConstData data,int source,int tag) {
     159             :   Request req;
     160             : #ifdef __PLUMED_HAS_MPI
     161       15206 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     162       15206 :   void*s=const_cast<void*>((const void*)data.pointer);
     163       15206 :   MPI_Isend(s,data.size,data.type,source,tag,communicator,&req.r);
     164             : #else
     165             :   (void) data;
     166             :   (void) source;
     167             :   (void) tag;
     168             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     169             : #endif
     170       15206 :   return req;
     171             : }
     172             : 
     173        2270 : void Communicator::Allgatherv(ConstData in,Data out,const int*recvcounts,const int*displs) {
     174             : #if defined(__PLUMED_HAS_MPI)
     175        2270 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     176        2270 :   void*s=const_cast<void*>((const void*)in.pointer);
     177        2270 :   void*r=const_cast<void*>((const void*)out.pointer);
     178             :   int*rc=const_cast<int*>(recvcounts);
     179             :   int*di=const_cast<int*>(displs);
     180        2270 :   if(s==NULL)s=MPI_IN_PLACE;
     181        2270 :   MPI_Allgatherv(s,in.size,in.type,r,rc,di,out.type,communicator);
     182             : #else
     183             :   (void) in;
     184             :   (void) out;
     185             :   (void) recvcounts;
     186             :   (void) displs;
     187             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     188             : #endif
     189        2270 : }
     190             : 
     191        4835 : void Communicator::Allgather(ConstData in,Data out) {
     192             : #if defined(__PLUMED_HAS_MPI)
     193        4835 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     194        4835 :   void*s=const_cast<void*>((const void*)in.pointer);
     195        4835 :   void*r=const_cast<void*>((const void*)out.pointer);
     196        4835 :   if(s==NULL)s=MPI_IN_PLACE;
     197        4835 :   MPI_Allgather(s,in.size,in.type,r,out.size/Get_size(),out.type,communicator);
     198             : #else
     199             :   (void) in;
     200             :   (void) out;
     201             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     202             : #endif
     203        4835 : }
     204             : 
     205       15206 : void Communicator::Recv(Data data,int source,int tag,Status&status) {
     206             : #ifdef __PLUMED_HAS_MPI
     207       15206 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     208       15206 :   if(&status==&StatusIgnore) MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,MPI_STATUS_IGNORE);
     209        7541 :   else                       MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,&status.s);
     210             : #else
     211             :   (void) data;
     212             :   (void) source;
     213             :   (void) tag;
     214             :   (void) status;
     215             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     216             : #endif
     217       15206 : }
     218             : 
     219             : 
     220             : 
     221             : 
     222             : 
     223     4042645 : void Communicator::Barrier()const {
     224             : #ifdef __PLUMED_HAS_MPI
     225     4042645 :   if(initialized()) MPI_Barrier(communicator);
     226             : #endif
     227     4042645 : }
     228             : 
     229        1310 : MPI_Comm & Communicator::Get_comm() {
     230        1310 :   return communicator;
     231             : }
     232             : 
     233    20434059 : bool Communicator::initialized() {
     234             : #if defined(__PLUMED_HAS_MPI)
     235    20434059 :   int flag=0;
     236    20434059 :   MPI_Initialized(&flag);
     237    20434059 :   if(flag) return true;
     238    11787415 :   else return false;
     239             : #endif
     240             :   return false;
     241             : }
     242             : 
     243       14814 : void Communicator::Request::wait(Status&s) {
     244             : #ifdef __PLUMED_HAS_MPI
     245       14814 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     246       14814 :   if(&s==&StatusIgnore) MPI_Wait(&r,MPI_STATUS_IGNORE);
     247           1 :   else MPI_Wait(&r,&s.s);
     248             : #else
     249             :   (void) s;
     250             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     251             : #endif
     252       14814 : }
     253             : 
     254             : #ifdef __PLUMED_HAS_MPI
     255           0 : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_FLOAT;}
     256     4002900 : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_DOUBLE;}
     257       33177 : template<> MPI_Datatype Communicator::getMPIType<int>()   { return MPI_INT;}
     258         234 : template<> MPI_Datatype Communicator::getMPIType<char>()   { return MPI_CHAR;}
     259        9346 : template<> MPI_Datatype Communicator::getMPIType<unsigned>()   { return MPI_UNSIGNED;}
     260     4038277 : template<> MPI_Datatype Communicator::getMPIType<long unsigned>()   { return MPI_UNSIGNED_LONG;}
     261             : #else
     262             : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_Datatype();}
     263             : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_Datatype();}
     264             : template<> MPI_Datatype Communicator::getMPIType<int>() { return MPI_Datatype();}
     265             : template<> MPI_Datatype Communicator::getMPIType<char>() { return MPI_Datatype();}
     266             : template<> MPI_Datatype Communicator::getMPIType<unsigned>() { return MPI_Datatype();}
     267             : template<> MPI_Datatype Communicator::getMPIType<long unsigned>() { return MPI_Datatype();}
     268             : #endif
     269             : 
     270             : 
     271         366 : void Communicator::Split(int color,int key,Communicator&pc)const {
     272             : #ifdef __PLUMED_HAS_MPI
     273         366 :   MPI_Comm_split(communicator,color,key,&pc.communicator);
     274             : #else
     275             :   (void) color;
     276             :   (void) key;
     277             :   (void) pc;
     278             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     279             : #endif
     280         366 : }
     281             : 
     282        7541 : int Communicator::Status::Get_count(MPI_Datatype type)const {
     283             :   int i;
     284             : #ifdef __PLUMED_HAS_MPI
     285        7541 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
     286        7541 :   MPI_Get_count(const_cast<MPI_Status*>(&s),type,&i);
     287             : #else
     288             :   i=0;
     289             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
     290             : #endif
     291        7541 :   return i;
     292             : }
     293             : 
     294        5517 : }
     295             : 

Generated by: LCOV version 1.14