LCOV - code coverage report
Current view: top level - tools - Communicator.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 83 105 79.0 %
Date: 2018-12-19 07:49:13 Functions: 26 32 81.2 %

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

Generated by: LCOV version 1.13