Commit 36d81639 authored by Tomáš Oberhuber's avatar Tomáš Oberhuber
Browse files

Added BiEllpack segments.

parent 429d197a
Loading
Loading
Loading
Loading
+138 −0
Original line number Diff line number Diff line
/***************************************************************************
                          BiEllpack.h -  description
                             -------------------
    begin                : Apr 5, 2020
    copyright            : (C) 2020 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#pragma once

#include <TNL/Allocators/Default.h>
#include <TNL/Containers/Vector.h>
#include <TNL/Containers/Segments/BiEllpackView.h>
#include <TNL/Containers/Segments/SegmentView.h>

namespace TNL {
   namespace Containers {
      namespace Segments {

template< typename Device,
          typename Index,
          typename IndexAllocator = typename Allocators::Default< Device >::template Allocator< Index >,
          bool RowMajorOrder = std::is_same< Device, Devices::Host >::value,
          int WarpSize = 32 >
class BiEllpack
{
   public:

      using DeviceType = Device;
      using IndexType = std::remove_const_t< Index >;
      using OffsetsHolder = Containers::Vector< Index, DeviceType, IndexType, IndexAllocator >;
      static constexpr bool getRowMajorOrder() { return RowMajorOrder; }
      using ViewType = BiEllpackView< Device, Index, RowMajorOrder >;
      template< typename Device_, typename Index_ >
      using ViewTemplate = BiEllpackView< Device_, Index_, RowMajorOrder >;
      using ConstViewType = BiEllpackView< Device, std::add_const_t< IndexType >, RowMajorOrder >;
      using SegmentViewType = BiEllpackSegmentView< IndexType, RowMajorOrder >;

      BiEllpack() = default;

      BiEllpack( const Vector< IndexType, DeviceType, IndexType >& sizes );

      BiEllpack( const BiEllpack& segments );

      BiEllpack( const BiEllpack&& segments );

      static String getSerializationType();

      static String getSegmentsType();

      ViewType getView();

      const ConstViewType getConstView() const;

      /**
       * \brief Set sizes of particular segments.
       */
      template< typename SizesHolder = OffsetsHolder >
      void setSegmentsSizes( const SizesHolder& sizes );

      __cuda_callable__
      IndexType getSegmentsCount() const;

      IndexType getSegmentSize( const IndexType segmentIdx ) const;

      /**
       * \brief Number segments.
       */
      __cuda_callable__
      IndexType getSize() const;

      __cuda_callable__
      IndexType getStorageSize() const;

      __cuda_callable__
      IndexType getGlobalIndex( const Index segmentIdx, const Index localIdx ) const;

      __cuda_callable__
      SegmentViewType getSegmentView( const IndexType segmentIdx ) const;

      /***
       * \brief Go over all segments and for each segment element call
       * function 'f' with arguments 'args'. The return type of 'f' is bool.
       * When its true, the for-loop continues. Once 'f' returns false, the for-loop
       * is terminated.
       */
      template< typename Function, typename... Args >
      void forSegments( IndexType first, IndexType last, Function& f, Args... args ) const;

      template< typename Function, typename... Args >
      void forAll( Function& f, Args... args ) const;


      /***
       * \brief Go over all segments and perform a reduction in each of them.
       */
      template< typename Fetch, typename Reduction, typename ResultKeeper, typename Real, typename... Args >
      void segmentsReduction( IndexType first, IndexType last, Fetch& fetch, Reduction& reduction, ResultKeeper& keeper, const Real& zero, Args... args ) const;

      template< typename Fetch, typename Reduction, typename ResultKeeper, typename Real, typename... Args >
      void allReduction( Fetch& fetch, Reduction& reduction, ResultKeeper& keeper, const Real& zero, Args... args ) const;

      BiEllpack& operator=( const BiEllpack& source ) = default;

      template< typename Device_, typename Index_, typename IndexAllocator_, bool RowMajorOrder_ >
      BiEllpack& operator=( const BiEllpack< Device_, Index_, IndexAllocator_, RowMajorOrder_, WarpSize >& source );

      void save( File& file ) const;

      void load( File& file );

      void printStructure( std::ostream& str ); // TODO const;

   protected:

      static constexpr int getWarpSize() { return WarpSize; };

      static constexpr int getLogWarpSize() { return std::log( WarpSize ); };

      IndexType size = 0, storageSize = 0;

      IndexType virtualRows = 0;

      OffsetsHolder rowPermArray;

      OffsetsHolder groupPointers;

      template< typename Device_, typename Index_, typename IndexAllocator_, bool RowMajorOrder_, int WarpSize_ >
      friend class BiEllpack;
};

      } // namespace Segements
   }  // namespace Conatiners
} // namespace TNL

#include <TNL/Containers/Segments/BiEllpack.hpp>
+320 −0
Original line number Diff line number Diff line
/***************************************************************************
                          BiEllpack.hpp -  description
                             -------------------
    begin                : Apr 5, 2020
    copyright            : (C) 2020 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#pragma once

#include <TNL/Containers/Vector.h>
#include <TNL/Algorithms/ParallelFor.h>
#include <TNL/Containers/Segments/BiEllpack.h>
#include <TNL/Containers/Segments/Ellpack.h>

namespace TNL {
   namespace Containers {
      namespace Segments {

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
BiEllpack( const Vector< IndexType, DeviceType, IndexType >& sizes )
{
   this->setSegmentsSizes( sizes );
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
BiEllpack( const BiEllpack& biEllpack )
   : size( biEllpack.size ),
     storageSize( biEllpack.storageSize ),
     virtualRows( biEllpack.virtualRows ),
     rowPermArray( biEllpack.rowPermArray ),
     groupPointers( biEllpack.groupPointers )
{
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
BiEllpack( const BiEllpack&& biEllpack )
   : size( biEllpack.size ),
     storageSize( biEllpack.storageSize ),
     virtualRows( biEllpack.virtualRows ),
     rowPermArray( std::move( biEllpack.rowPermArray ) ),
     groupPointers( std::move( biEllpack.groupPointers ) )
{
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
String
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getSerializationType()
{
   return "BiEllpack< [any_device], " + TNL::getSerializationType< IndexType >() + " >";
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
String
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getSegmentsType()
{
   return ViewType::getSegmentsType();
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
typename BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::ViewType
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getView()
{
   return ViewType( size, storageSize, virtualRows, rowPermArray.getView(), groupPointers.getView() );
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
auto BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getConstView() const -> const ConstViewType
{
   return ConstViewType( size, storageSize, virtualRows, rowPermArray.getConstView(), groupPointers.getConstView() );
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
   template< typename SizesHolder >
void
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
setSegmentsSizes( const SizesHolder& segmentsSizes )
{
   if( std::is_same< DeviceType, Devices::Host >::value )
   {
   }
   else
   {
      BiEllpack< Devices::Host, Index, typename Allocators::Default< Devices::Host >::template Allocator< Index >, RowMajorOrder > hostSegments;
      Containers::Vector< IndexType, Devices::Host, IndexType > hostSegmentsSizes( segmentsSizes );
      hostSegments.setSegmentsSizes( hostSegmentsSizes );
      *this = hostSegments;
   }
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
__cuda_callable__ auto BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getSegmentsCount() const -> IndexType
{
   return this->segmentsCount;
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
auto BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getSegmentSize( const IndexType segmentIdx ) const -> IndexType
{
   return details::BiEllpack< IndexType, DeviceType, RowMajorOrder >::getSegmentSize(
      rowPermArray.getConstView(),
      groupPointers.getConstView(),
      segmentIdx );
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
__cuda_callable__ auto BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getSize() const -> IndexType
{
   return this->size;
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
__cuda_callable__ auto BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getStorageSize() const -> IndexType
{
   return this->storageSize;
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
__cuda_callable__ auto BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getGlobalIndex( const Index segmentIdx, const Index localIdx ) const -> IndexType
{
      return details::BiEllpack< IndexType, DeviceType, RowMajorOrder >::getGlobalIndex(
         rowPermArray.getConstView(),
         groupPointers.getConstView(),
         segmentIdx,
         localIdx );
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
__cuda_callable__ auto BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
getSegmentView( const IndexType segmentIdx ) const -> SegmentViewType
{
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
   template< typename Function, typename... Args >
void
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
forSegments( IndexType first, IndexType last, Function& f, Args... args ) const
{
   this->getConstView().forSegments( first, last, f, args... );
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
   template< typename Function, typename... Args >
void
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
forAll( Function& f, Args... args ) const
{
   this->forSegments( 0, this->getSegmentsCount(), f, args... );
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
   template< typename Fetch, typename Reduction, typename ResultKeeper, typename Real, typename... Args >
void
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
segmentsReduction( IndexType first, IndexType last, Fetch& fetch, Reduction& reduction, ResultKeeper& keeper, const Real& zero, Args... args ) const
{
   this->getConstView().segmentsReduction( first, last, fetch, reduction, keeper, zero, args... );
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
   template< typename Fetch, typename Reduction, typename ResultKeeper, typename Real, typename... Args >
void
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
allReduction( Fetch& fetch, Reduction& reduction, ResultKeeper& keeper, const Real& zero, Args... args ) const
{
   this->segmentsReduction( 0, this->getSegmentsCount(), fetch, reduction, keeper, zero, args... );
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
   template< typename Device_, typename Index_, typename IndexAllocator_, bool RowMajorOrder_ >
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >&
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
operator=( const BiEllpack< Device_, Index_, IndexAllocator_, RowMajorOrder_, WarpSize >& source )
{
   this->size = source.size;
   this->storageSize = source.storageSize;
   this->virtualRows = source.virtualRows;
   this->rowPermArray = source.rowPermArray;
   this->groupPointers = source.groupPointers;
   return *this;
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
void
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
save( File& file ) const
{
   file.save( &this->size );
   file.save( &this->storageSize );
   file.save( &this->virtualRows );
   file << this->rowPermArray
        << this->groupPointers;
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
void
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
load( File& file )
{
   file.load( &this->size );
   file.load( &this->storageSize );
   file.load( &this->virtualRows );
   file >> this->rowPermArray
        >> this->groupPointers;
}

template< typename Device,
          typename Index,
          typename IndexAllocator,
          bool RowMajorOrder,
          int WarpSize >
void
BiEllpack< Device, Index, IndexAllocator, RowMajorOrder, WarpSize >::
printStructure( std::ostream& str )
{
   this->getView().printStructure( str );
}

      } // namespace Segments
   }  // namespace Conatiners
} // namespace TNL
+94 −0
Original line number Diff line number Diff line
/***************************************************************************
                          BiEllpackSegmentView.h -  description
                             -------------------
    begin                : Apr 7, 2020
    copyright            : (C) 2020 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#pragma once

namespace TNL {
   namespace Containers {
      namespace Segments {

template< typename Index,
          bool RowMajorOrder = false >
class BiEllpackSegmentView;

template< typename Index >
class BiEllpackSegmentView< Index, false >
{
   public:

      using IndexType = Index;

      __cuda_callable__
      BiEllpackSegmentView( const IndexType offset,
                                 const IndexType size,
                                 const IndexType chunkSize,      // this is only for compatibility with the following specialization
                                 const IndexType chunksInSlice ) // this one as well - both can be replaced when we could use constexprif in C++17
      : segmentOffset( offset ), segmentSize( size ){};

      __cuda_callable__
      BiEllpackSegmentView( const BiEllpackSegmentView& view )
      : segmentOffset( view.segmentOffset ), segmentSize( view.segmentSize ){};

      __cuda_callable__
      IndexType getSize() const
      {
         return this->segmentSize;
      };

      __cuda_callable__
      IndexType getGlobalIndex( const IndexType localIndex ) const
      {
         TNL_ASSERT_LT( localIndex, segmentSize, "Local index exceeds segment bounds." );
         return segmentOffset + localIndex;
      };

      protected:
         
         IndexType segmentOffset, segmentSize;
};

template< typename Index >
class BiEllpackSegmentView< Index, true >
{
   public:

      using IndexType = Index;

      __cuda_callable__
      BiEllpackSegmentView( const IndexType offset,
                                 const IndexType size,
                                 const IndexType chunkSize,
                                 const IndexType chunksInSlice )
      : segmentOffset( offset ), segmentSize( size ),
        chunkSize( chunkSize ), chunksInSlice( chunksInSlice ){};

      __cuda_callable__
      IndexType getSize() const
      {
         return this->segmentSize;
      };

      __cuda_callable__
      IndexType getGlobalIndex( const IndexType localIdx ) const
      {
         TNL_ASSERT_LT( localIdx, segmentSize, "Local index exceeds segment bounds." );
         const IndexType chunkIdx = localIdx / chunkSize;
         const IndexType inChunkOffset = localIdx % chunkSize;
         return segmentOffset + inChunkOffset * chunksInSlice + chunkIdx;
      };

      protected:
         
         IndexType segmentOffset, segmentSize, chunkSize, chunksInSlice;
};

      } //namespace Segments
   } //namespace Containers
} //namespace TNL
+204 −0

File added.

Preview size limit exceeded, changes collapsed.

+490 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading