Skip to content
Snippets Groups Projects
Partitioner.h 2.69 KiB
Newer Older
  • Learn to ignore specific revisions
  • /***************************************************************************
    
                              Partitioner.h  -  description
    
                                 -------------------
        begin                : Sep 6, 2018
        copyright            : (C) 2018 by Tomas Oberhuber et al.
        email                : tomas.oberhuber@fjfi.cvut.cz
     ***************************************************************************/
    
    /* See Copyright Notice in tnl/Copyright */
    
    // Implemented by: Jakub Klinkovský
    
    #pragma once
    
    
    #include "Subrange.h"
    
    
    #include <TNL/Math.h>
    
    namespace TNL {
    namespace DistributedContainers {
    
    template< typename Index, typename Communicator >
    
    class Partitioner
    
    {
       using CommunicationGroup = typename Communicator::CommunicationGroup;
    public:
    
       using SubrangeType = Subrange< Index >;
    
       static SubrangeType splitRange( Index globalSize, CommunicationGroup group )
    
       {
          if( group != Communicator::NullGroup ) {
             const int rank = Communicator::GetRank( group );
             const int partitions = Communicator::GetSize( group );
             const Index begin = min( globalSize, rank * globalSize / partitions );
             const Index end = min( globalSize, (rank + 1) * globalSize / partitions );
    
             return SubrangeType( begin, end );
    
             return SubrangeType( 0, 0 );
    
    
       // Gets the owner of given global index.
       __cuda_callable__
       static int getOwner( Index i, Index globalSize, int partitions )
       {
    
          int owner = i * partitions / globalSize;
          if( owner < partitions - 1 && i >= getOffset( globalSize, owner + 1, partitions ) )
             owner++;
          TNL_ASSERT_GE( i, getOffset( globalSize, owner, partitions ), "BUG in getOwner" );
          TNL_ASSERT_LT( i, getOffset( globalSize, owner + 1, partitions ), "BUG in getOwner" );
          return owner;
    
       }
    
       // Gets the offset of data for given rank.
       __cuda_callable__
       static Index getOffset( Index globalSize, int rank, int partitions )
       {
          return rank * globalSize / partitions;
       }
    
       // Gets the size of data assigned to given rank.
       __cuda_callable__
       static Index getSizeForRank( Index globalSize, int rank, int partitions )
       {
          const Index begin = min( globalSize, rank * globalSize / partitions );
          const Index end = min( globalSize, (rank + 1) * globalSize / partitions );
          return end - begin;
       }
    
    // TODO:
    // - partitioner in deal.II stores also ghost indices:
    //   https://www.dealii.org/8.4.0/doxygen/deal.II/classUtilities_1_1MPI_1_1Partitioner.html
    // - ghost indices are stored in a general IndexMap class (based on collection of subranges):
    //   https://www.dealii.org/8.4.0/doxygen/deal.II/classIndexSet.html
    
    
    } // namespace DistributedContainers
    } // namespace TNL