LCOV - code coverage report
Current view: top level - coupling/paralleltopology - ZYXTopology.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 21 21
Test Date: 2026-08-21 15:14:06 Functions: 80.0 % 10 8

            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 2.0-1