LCOV - code coverage report
Current view: top level - include/dash - Distribution.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 33 35 94.3 %
Date: 2016-06-29 12:30:40 Functions: 10 10 100.0 %

          Line data    Source code
       1             : #ifndef DASH__DISTRIBUTION_H_
       2             : #define DASH__DISTRIBUTION_H_
       3             : 
       4             : #include <dash/Types.h>
       5             : #include <dash/Exception.h>
       6             : #include <dash/internal/Math.h>
       7             : #include <dash/internal/Logging.h>
       8             : 
       9             : namespace dash {
      10             : 
      11             : /**
      12             :  * Specifies how a Pattern distributes elements to units
      13             :  * in a specific dimension.
      14             :  *
      15             :  * Predefined configurations are
      16             :  *   * dash::BLOCKED
      17             :  *   * dash::BLOCKCYCLIC
      18             :  *   * dash::CYCLIC
      19             :  *   * dash::TILE
      20             :  *   * dash::NONE
      21             :  *
      22             :  * \see Pattern
      23             :  */
      24             : class Distribution
      25             : {
      26             : private:
      27             :   typedef Distribution self_t;
      28             : 
      29             :   friend std::ostream & operator<<(
      30             :     std::ostream & os,
      31             :     const self_t & distribution);
      32             : 
      33             : public:
      34             :   dash::internal::DistributionType type;
      35             :   dash::default_size_t             blocksz;
      36             : 
      37             :   /**
      38             :    * Constructor, initializes Distribution with distribution
      39             :    * type NONE.
      40             :    */
      41      507503 :   Distribution()
      42             :   : type(dash::internal::DIST_NONE),
      43      507503 :     blocksz(0) {
      44      507503 :   }
      45             : 
      46             :   /**
      47             :    * Constructor, initializes Distribution with a
      48             :    * distribution type and a block size.
      49             :    */
      50         394 :   Distribution(
      51             :     dash::internal::DistributionType distType,
      52             :     int                              blockSize)
      53             :   : type(distType),
      54         394 :     blocksz(blockSize) {
      55         394 :   }
      56             : 
      57     8427278 :   Distribution(const self_t & other)
      58     8427278 :   : type(other.type),
      59     8427278 :     blocksz(other.blocksz) {
      60     8427278 :   }
      61             : 
      62      507691 :   self_t & operator=(const self_t & other) {
      63      507691 :     type    = other.type;
      64      507691 :     blocksz = other.blocksz;
      65      507691 :     return *this;
      66             :   }
      67             : 
      68             :   /**
      69             :    * Resolve the block coordinate for a given local index
      70             :    * in the distribution's dimension.
      71             :    */
      72             :   template <typename IndexType, typename SizeType>
      73     8423650 :   inline IndexType local_index_to_block_coord(
      74             :     // The unit's offset in the distribution's dimension
      75             :     // within the global team specification
      76             :     IndexType unit_teamspec_coord,
      77             :     // Local index of the element
      78             :     IndexType local_index,
      79             :     // Number of units in the distribution's dimension
      80             :     SizeType num_units_in_dim,
      81             :     // Number of blocks in the distribution's dimension
      82             :     SizeType num_blocks_in_dim,
      83             :     // Number of elements in the distribution's dimension in a single block
      84             :     SizeType blocksize) const {
      85             :     // NOTE: blocksize should be this->blocksz
      86     8423650 :     SizeType local_block_offset = 0;
      87     8423650 :     switch (type) {
      88             :       case dash::internal::DIST_NONE:
      89             :         // There is only one block in this dimension, so
      90             :         // block coordinate is 0:
      91       17886 :         return 0;
      92             :       case dash::internal::DIST_BLOCKED:
      93             :         // Same as blockcyclic, but local block offset is
      94             :         // always 0:
      95        5128 :         return unit_teamspec_coord;
      96             :       case dash::internal::DIST_TILE:
      97             :         // Same as blockcyclic
      98             :       case dash::internal::DIST_BLOCKCYCLIC:
      99             :         // Number of blocks local to the unit that are
     100             :         // in front of the given local index:
     101     8399596 :         local_block_offset = local_index / blocksz;
     102             :         // Number of blocks of any unit that are in front
     103             :         // of the given local index. Unit's coordinate in team
     104             :         // spec is equivalent to the number of units in front of
     105             :         // the unit.
     106             :         return (local_block_offset * num_units_in_dim) +
     107     8399596 :                   unit_teamspec_coord;
     108             :       case dash::internal::DIST_CYCLIC:
     109             :         // Like blockcyclic, but with blocksize 1:
     110             :         DASH_LOG_TRACE("Distribution.local_index_to_block_coord",
     111             :                        "unit_teamspec_coord", unit_teamspec_coord,
     112             :                        "local_index", local_index,
     113             :                        "num_units_in_dim", num_units_in_dim);
     114        1040 :         return unit_teamspec_coord + local_index * num_units_in_dim;
     115             :       default:
     116           0 :         DASH_THROW(
     117             :           dash::exception::InvalidArgument,
     118             :           "Distribution type undefined in " <<
     119             :           "local_index_to_block_coord");
     120             :     }
     121             :   }
     122             : 
     123             :   /**
     124             :    * Resolve the global block coordinate for a given local block index
     125             :    * in the distribution's dimension.
     126             :    */
     127             :   template <typename IndexType, typename SizeType>
     128             :   inline IndexType local_to_global_block_coord(
     129             :     // The unit's offset in the distribution's dimension
     130             :     // within the global team specification
     131             :     IndexType unit_teamspec_coord,
     132             :     // Local index of the block
     133             :     IndexType local_block_index,
     134             :     // Number of units in the distribution's dimension
     135             :     SizeType num_units_in_dim,
     136             :     // Number of blocks in the distribution's dimension
     137             :     SizeType num_blocks_in_dim,
     138             :     // Number of elements in the distribution's dimension in a single block
     139             :     SizeType blocksize) const {
     140             :   }
     141             : 
     142             :   /**
     143             :    * The maximum size of a single block within an extent for
     144             :    * a given total number of units.
     145             :    */
     146             :   template <typename IndexType, typename SizeType>
     147         800 :   inline IndexType max_blocksize_in_range(
     148             :     /// Number of elements to distribute
     149             :     IndexType range,
     150             :     /// Number of units to which elements are distributed
     151             :     SizeType num_units) const
     152             :   {
     153             :     DASH_LOG_TRACE("Distribution.max_blocksize_in_range()",
     154             :                    "range:", range, "nunits:", num_units);
     155         800 :     switch (type) {
     156             :       case dash::internal::DIST_NONE:
     157         101 :         return range;
     158             :       case dash::internal::DIST_BLOCKED:
     159         300 :         return num_units == 0 ? 0 : dash::math::div_ceil(range, num_units);
     160             :       case dash::internal::DIST_CYCLIC:
     161          17 :         return 1;
     162             :       case dash::internal::DIST_BLOCKCYCLIC:
     163             :       case dash::internal::DIST_TILE:
     164             :         DASH_LOG_TRACE("Distribution.max_blocksize_in_range",
     165             :                        "TILE", "blocksz:", blocksz);
     166             :         // Shrink block size in dimension if it exceeds the number
     167             :         // of elements in dimension:
     168         382 :         return std::min<SizeType>(range, blocksz);
     169             :       default:
     170           0 :         DASH_THROW(
     171             :           dash::exception::InvalidArgument,
     172             :           "Distribution type undefined in max_blocksize_in_range");
     173             :     }
     174             :   }
     175             : 
     176             :   /**
     177             :    * Equality comparison operator.
     178             :    */
     179          51 :   bool operator==(const Distribution & other) const {
     180         101 :     return (this->type == other.type &&
     181         101 :             this->blocksz == other.blocksz);
     182             :   }
     183             :   /**
     184             :    * Inequality comparison operator.
     185             :    */
     186          51 :   bool operator!=(const Distribution & other) const {
     187          51 :     return !(*this == other);
     188             :   }
     189             : };
     190             : 
     191             : /**
     192             :  * Distribution specifying that elements in a Pattern's
     193             :  * dimension shall be distributed to units in even-sized
     194             :  * blocks.
     195             :  *
     196             :  * \relates Distribution
     197             :  */
     198             : extern const Distribution BLOCKED;
     199             : /**
     200             :  * Distribution specifying that elements in a Pattern's
     201             :  * dimension shall be distributed by cycling among units.
     202             :  * Semantically equivalent to BLOCKCYCLIC(1) but with slight
     203             :  * performance improvement.
     204             :  *
     205             :  * \relates Distribution
     206             :  */
     207             : extern const Distribution CYCLIC;
     208             : /**
     209             :  * Distribution specifying that elements in a Pattern's
     210             :  * dimension shall not be distributed.
     211             :  *
     212             :  * \relates Distribution
     213             :  */
     214             : extern const Distribution NONE;
     215             : 
     216             : /**
     217             :  * Distribution specifying that elements in a Pattern's
     218             :  * dimension shall be distributed to units in a tiled blocks of
     219             :  * the given size.
     220             :  *
     221             :  * \relates Distribution
     222             :  */
     223             : Distribution TILE(int blockSize);
     224             : 
     225             : /**
     226             :  * Distribution specifying that elements in a Pattern's
     227             :  * dimension shall be distributed to units in blocks of the
     228             :  * given size.
     229             :  *
     230             :  * \relates Distribution
     231             :  */
     232             : Distribution BLOCKCYCLIC(int blockSize);
     233             : 
     234             : } // namespace dash
     235             : 
     236             : #endif // DASH__DISTRIBUTION_H_

Generated by: LCOV version 1.12