LCOV - code coverage report
Current view: top level - coupling/paralleltopology - ZYXTopology.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 21 21 100.0 %
Date: 2025-06-25 11:26:37 Functions: 8 12 66.7 %

          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_PARALLELTOPOLOGY_ZYXTOPOLOGY_H_
       6             : #define _MOLECULARDYNAMICS_COUPLING_PARALLELTOPOLOGY_ZYXTOPOLOGY_H_
       7             : 
       8             : #include "coupling/CouplingMDDefinitions.h"
       9             : #include "coupling/paralleltopology/ParallelTopology.h"
      10             : 
      11             : namespace coupling {
      12             : namespace paralleltopology {
      13             : template <unsigned int dim> class ZYXTopology;
      14             : }
      15             : } // namespace coupling
      16             : 
      17             : /** In the ZYXTopology, the process coordinates convert to a rank as
      18             :  *  rank = x*ny*nz + y*nz + z = z + nz*(y+ny*x) (for 3D).
      19             :  *  topologyOffset is used for linearized access of multiple MD instances.
      20             :  *  Derived class from the class ParallelTopology. E.g. assuming
      21             :  *  ParallelTopologyType = XYZ and there is a cubic domain, splitted into 8
      22             :  *  sub-domains (2 sub-domains in each dimension). Then the ordering of the MPI
      23             :  *  processes is: Rank=0 for x=0,y=0,z=0. Rank=1 for x=0,y=0,z=1. Rank=2 for
      24             :  *  x=0,y=1,z=0. Rank=3 for x=0,y=1,z=1. Rank=4 for x=1,y=0,z=0. Rank=5 for
      25             :  *  x=1,y=0,z=1. Rank=6 for x=1,y=1,z=0. Rank=7 for x=1,y=1,z=1.
      26             :  *      @brief The ZYXTopology orders the ranks in z-y-x manner.
      27             :  *      @tparam dim Number of dimensions; it can be 1, 2 or 3
      28             :  *  @author Philipp Neumann
      29             :  *      @todo Philipp could you please take a look on this class
      30             :  */
      31             : template <unsigned int dim> class coupling::paralleltopology::ZYXTopology : public coupling::paralleltopology::ParallelTopology<dim> {
      32             : public:
      33             :   /** Constructor */
      34          24 :   ZYXTopology(tarch::la::Vector<dim, unsigned int> numberProcesses)
      35          48 :       : coupling::paralleltopology::ParallelTopology<dim>(), _numberProcesses(numberProcesses),
      36          48 :         _divisionFactor4NumberProcesses(initDivisionFactor(numberProcesses)) {}
      37             : 
      38             :   /** Destructor */
      39          24 :   virtual ~ZYXTopology() {}
      40             : 
      41         560 :   tarch::la::Vector<dim, unsigned int> getProcessCoordinates(unsigned int rank, unsigned int topologyOffset) const {
      42         560 :     tarch::la::Vector<dim, unsigned int> processCoordinates(0);
      43         560 :     unsigned int help = rank - topologyOffset;
      44        2160 :     for (unsigned int d = 0; d < dim; d++) {
      45        1600 :       processCoordinates[d] = help / _divisionFactor4NumberProcesses[d];
      46        1600 :       help = help - processCoordinates[d] * _divisionFactor4NumberProcesses[d];
      47             :     }
      48             : #if (COUPLING_MD_DEBUG == COUPLING_MD_YES)
      49             :     std::cout << "Rank=" << rank << " corresponds to process coordinates=" << processCoordinates << std::endl;
      50             : #endif
      51         560 :     return processCoordinates;
      52             :   }
      53             : 
      54             :   /** computes the rank as shown above, see second formula of class definition
      55             :    */
      56         144 :   unsigned int getRank(tarch::la::Vector<dim, unsigned int> processCoordinates, unsigned int topologyOffset) const {
      57         144 :     unsigned int rank = processCoordinates[0];
      58         408 :     for (unsigned int d = 1; d < dim; d++) {
      59         264 :       rank = rank * _numberProcesses[d] + processCoordinates[d];
      60             :     }
      61         144 :     return rank + topologyOffset;
      62             :   }
      63             : 
      64             : private:
      65             :   /** sets the division factor for each vector entry. For ZYX, this corresponds
      66             :    * to (in 3D) (ny*nz,nz,1) and to (2D) (ny,1). */
      67          24 :   tarch::la::Vector<dim, unsigned int> initDivisionFactor(tarch::la::Vector<dim, unsigned int> numberProcesses) const {
      68          24 :     tarch::la::Vector<dim, unsigned int> div(1);
      69          60 :     for (int d = dim - 2; d > -1; d--) {
      70          36 :       div[d] = div[d + 1] * numberProcesses[d + 1];
      71             :     }
      72          24 :     return div;
      73             :   }
      74             : 
      75             :   /* number of processes */
      76             :   const tarch::la::Vector<dim, unsigned int> _numberProcesses;
      77             :   /* division factor */
      78             :   const tarch::la::Vector<dim, unsigned int> _divisionFactor4NumberProcesses;
      79             : };
      80             : #endif // _MOLECULARDYNAMICS_COUPLING_PARALLELTOPOLOGY_ZYXTOPOLOGY_H_

Generated by: LCOV version 1.14