LCOV - code coverage report
Current view: top level - coupling/sendrecv - SendReceiveBuffer.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 7 0
Test Date: 2026-08-21 15:14:06 Functions: 0.0 % 1 0

            Line data    Source code
       1              : // Copyright (C) 2015 Technische Universitaet Muenchen
       2              : // This file is part of the Mamico project. For conditions of distribution
       3              : // and use, please see the copyright notice in Mamico's main folder, or at
       4              : // www5.in.tum.de/mamico
       5              : #ifndef _MOLECULARDYNAMICS_COUPLING_SENDRECV_SENDRECEIVEBUFFER_H_
       6              : #define _MOLECULARDYNAMICS_COUPLING_SENDRECV_SENDRECEIVEBUFFER_H_
       7              : 
       8              : #include "DataExchangeFromMD2Macro.h"
       9              : #include "coupling/CouplingMDDefinitions.h"
      10              : #include "coupling/indexing/IndexingService.h"
      11              : #include "coupling/sendrecv/DataExchange.h"
      12              : #include "tarch/la/Vector.h"
      13              : #include <algorithm>
      14              : #include <map>
      15              : #include <set>
      16              : #include <string.h>
      17              : #if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
      18              : #include <mpi.h>
      19              : #endif
      20              : 
      21              : namespace coupling {
      22              : namespace sendrecv {
      23              : template <class Cell_T, unsigned int dim> class SendReceiveBuffer;
      24              : }
      25              : } // namespace coupling
      26              : 
      27              : /** generic class for send-/ receive methodology including buffer
      28              :  *implementations. The access to the buffers is prescribed by the DataExchange
      29              :  *object.
      30              :  *      @brief generic class for send-/ receive methodology.
      31              :  *      @tparam Cell_T cell type
      32              :  *      @tparam dim Number of dimensions; it can be 1, 2 or 3
      33              :  *  @author Philipp Neumann
      34              :  */
      35              : template <class Cell_T, unsigned int dim> class coupling::sendrecv::SendReceiveBuffer {
      36              : public:
      37              :   /** Constructor */
      38              :   SendReceiveBuffer();
      39              :   /** Destructor */
      40              :   virtual ~SendReceiveBuffer();
      41              : 
      42              : protected:
      43              :   /** @brief deletes the buffers */
      44              :   void deleteBuffers();
      45              : 
      46              :   /** @brief fills all information that needs to be sent from a coupling cell
      47              :    * into the send-buffer.
      48              :    *    @param dataExchange
      49              :    *    @param cells
      50              :    */
      51              :   template <class Container_T> void writeToSendBuffer(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange, const Container_T& cells);
      52              : 
      53              :   /** @brief fills all information that needs to be broadcast from a coupling cell
      54              :    * into the broadcast-buffer.
      55              :    *    @param dataExchange
      56              :    *    @param cell
      57              :    *    @param idx
      58              :    */
      59              :   void writeToBcastBuffer(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange, const Cell_T& cell, I01 idx);
      60              : 
      61              :   /** @brief fills all information that needs to be reduced to a coupling cell
      62              :    * into the reduce-buffer.
      63              :    *    @param dataExchange
      64              :    *    @param cell
      65              :    *    @param idx
      66              :    */
      67              :   void writeToReduceBuffer(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange, const Cell_T& cell, I01 idx);
      68              : 
      69              :   /** reads the information from the receive-buffer and fills it into a
      70              :    * coupling cell.
      71              :    *    @param dataExchange
      72              :    *    @param couplingCell
      73              :    *    @param idx
      74              :    */
      75              :   template <class Container_T> void readFromReceiveBuffer(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange, const Container_T& cells);
      76              : 
      77              :   void readFromCollectiveBuffer(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange, Cell_T& couplingCell, I01 idx);
      78              : 
      79              :   /** reads the information from the reduce-buffer and fills it into a
      80              :    * coupling cell.
      81              :    *    @param dataExchange
      82              :    *    @param couplingCell
      83              :    *    @param idx
      84              :    */
      85              :   void readFromReduceBuffer(coupling::sendrecv::DataExchangeFromMD2Macro<dim>& dataExchange, Cell_T& couplingCell, I01 idx);
      86              : 
      87              :   /** according to rule by dataExchange, the receive buffers are allocated. This
      88              :    * function adds a contribution for the cell at idx.
      89              :    *    @param dataExchange
      90              :    *    @param idx
      91              :    */
      92              :   void allocateReceiveBuffers(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange, I01 idx);
      93              : 
      94              :   /** Allocates buffer for receiving in the context of the broadcast operation
      95              :    *    @param dataExchange
      96              :    *    @param idx
      97              :    */
      98              :   void allocateBcastBufferForReceiving(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange, I01 idx);
      99              : 
     100              :   /** Allocates buffer for receiving in the context of the reduce operation
     101              :    *    @param dataExchange
     102              :    *    @param idx
     103              :    */
     104              :   void allocateReduceBufferForReceiving(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange, I01 idx);
     105              : 
     106              :   /** triggers the MPI-sending on the respective buffers. No sending for
     107              :    * information transfer from/ to this rank.
     108              :    *    @param dataExchange
     109              :    */
     110              :   void triggerSending(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange);
     111              : 
     112              :   /** triggers the MPI-broadcast on the respective buffers.
     113              :    *    @param rank
     114              :    */
     115              :   void triggerBcasts(unsigned int rank);
     116              : 
     117              :   /** triggers the MPI-receiving on the respective buffers. No receiving of
     118              :    * information from/to this rank.
     119              :    *    @param dataExchange
     120              :    */
     121              :   void triggerReceiving(coupling::sendrecv::DataExchange<Cell_T, dim>& dataExchange);
     122              : 
     123              :   /** triggers the MPI-reduce on the respective buffers.
     124              :    *    @param rank
     125              :    */
     126              :   void triggerReduce(unsigned int rank);
     127              : 
     128              :   /** wait for all send and receive operations to complete.
     129              :    */
     130              :   void waitAllOperations();
     131              : 
     132              :   /** wait for all broadcast or reduce operations to complete */
     133              :   void waitAllCollectiveOperations();
     134              : 
     135              :   /** allocates send and receive requests
     136              :    */
     137              :   void allocateRequests();
     138              : 
     139              :   /** allocates broadcast request
     140              :    *    @param thisRank
     141              :    */
     142              :   void allocateBcastRequests(unsigned int thisRank);
     143              : 
     144              :   /** allocates reduce request
     145              :    *    @param thisRank
     146              :    */
     147              :   void allocateReduceRequests(unsigned int thisRank);
     148              : 
     149              : private:
     150              :   /** data structure for send- and receive-buffer. */
     151              :   struct BufferWithID {
     152              :     double* buffer;
     153              :     unsigned int bufferSize;
     154              : 
     155            0 :     BufferWithID() : buffer(NULL), bufferSize(0) {}
     156              :   };
     157              : 
     158              :   struct BufferCollective {
     159              :     std::vector<double> buffer;
     160              :     std::set<unsigned int> nonRootRanks;
     161              :     std::set<unsigned int> cellIndices;
     162              :     unsigned int rootRank;
     163              : 
     164              :     BufferCollective() : buffer(), nonRootRanks(), cellIndices(), rootRank(UINT_MAX) {}
     165              :   };
     166              : 
     167              :   /** deletes everything inside a given buffer
     168              :    *    @param buffer
     169              :    */
     170              :   void deleteBuffer(std::map<unsigned int, BufferWithID>& buffer);
     171              : 
     172              :   /** buffer for storing all received messages from MD. Each map entry is
     173              :    * identified by a respective rank. */
     174              :   std::map<unsigned int, BufferWithID> _receiveBuffer;
     175              :   std::map<unsigned int, BufferWithID> _sendBuffer;
     176              : 
     177              :   /** members for collective communication */
     178              :   std::map<unsigned int, BufferCollective> _bcastBuffer;
     179              :   std::map<unsigned int, BufferCollective> _reduceBuffer;
     180              : 
     181              : #if (COUPLING_MD_PARALLEL == COUPLING_MD_YES)
     182              :   bool _requestsAllocated; /** flag that will always be reset after every send
     183              :                               operation. Triggers instantiation of requests */
     184              :   MPI_Request* _requests;
     185              :   int _receiveSize; /** number of receive requests */
     186              :   int _sendSize;    /** number of send requests */
     187              : 
     188              :   std::vector<MPI_Comm> _subComms;
     189              :   std::vector<MPI_Group> _subGroups;
     190              :   int _bcastOrReduceSize;
     191              : 
     192            0 :   static void elementWiseSum(void* in, void* inout, int* len, MPI_Datatype* datatype) {
     193            0 :     auto* output = (double*)inout;
     194            0 :     auto* input = (double*)in;
     195            0 :     for (int i = 0; i < *len; ++i) {
     196            0 :       output[i] += input[i];
     197              :     }
     198            0 :   }
     199              : 
     200              :   MPI_Op elementWiseSumOperation;
     201              : #endif
     202              : };
     203              : 
     204              : #include "SendReceiveBuffer.cpph"
     205              : 
     206              : #endif // _MOLECULARDYNAMICS_COUPLING_SENDRECV_SENDRECEIVEBUFFER_H_
        

Generated by: LCOV version 2.0-1