Commit 2e8dfa1e authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Cleanup: removed multimaps classes as they were superseded with sparse binary matrices

parent fe5e1351
Loading
Loading
Loading
Loading
+0 −116
Original line number Diff line number Diff line
/***************************************************************************
                          EllpackIndexMultimap.h  -  description
                             -------------------
    begin                : Sep 9, 2015
    copyright            : (C) 2015 by Tomas Oberhuber et al.
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#pragma once

#include <TNL/Containers/Vector.h>
#include <TNL/Containers/Multimaps/EllpackIndexMultimapValues.h>

namespace TNL {
namespace Containers {
namespace Multimaps {

template< typename Device >
struct EllpackIndexMultimapSliceSizeGetter
{
   static constexpr int SliceSize = 1;
};

template<>
struct EllpackIndexMultimapSliceSizeGetter< Devices::Cuda >
{
   static constexpr int SliceSize = 32;
};

template< typename Index = int,
          typename Device = Devices::Host,
          typename LocalIndex = Index,
          int SliceSize = EllpackIndexMultimapSliceSizeGetter< Device >::SliceSize >
class EllpackIndexMultimap
   : public Object
{
   public:
      using DeviceType                 = Device;
      using IndexType                  = Index;
      using LocalIndexType             = LocalIndex;
      using ValuesAccessorType         = EllpackIndexMultimapValues< IndexType, DeviceType, LocalIndexType, SliceSize >;
      using ConstValuesAccessorType    = EllpackIndexMultimapValues< const IndexType, DeviceType, LocalIndexType, SliceSize >;
      using ValuesAllocationVectorType = Vector< LocalIndexType, DeviceType, IndexType >;

      EllpackIndexMultimap() = default;

      template< typename Device_ >
      EllpackIndexMultimap( const EllpackIndexMultimap< Index, Device_, LocalIndex, SliceSize >& other );

      template< typename Device_ >
      EllpackIndexMultimap& operator=( const EllpackIndexMultimap< Index, Device_, LocalIndex, SliceSize >& other );

      void setKeysRange( const IndexType& keysRange );

      __cuda_callable__
      const IndexType getKeysRange() const;

      void allocate( const LocalIndexType& maxValuesCount );

      void allocate( const ValuesAllocationVectorType& valuesCounts );

      template< typename Device_, int SliceSize_ >
      void setLike( const EllpackIndexMultimap< Index, Device_, LocalIndex, SliceSize_ >& other );

      __cuda_callable__
      ValuesAccessorType getValues( const IndexType& inputIndex );

      __cuda_callable__
      ConstValuesAccessorType getValues( const IndexType& inputIndex ) const;

      __cuda_callable__
      LocalIndexType getValuesCount( const IndexType& inputIndex ) const;

      __cuda_callable__
      IndexType getValue( const IndexType& inputIndex, const LocalIndexType& portIndex ) const;

      bool operator==( const EllpackIndexMultimap& other ) const;

      void save( File& file ) const;

      void load( File& file );

      using Object::load;

      using Object::save;

      void print( std::ostream& str ) const;

   protected:
      Vector< IndexType, DeviceType, IndexType > values;
      ValuesAllocationVectorType valuesCounts;

      IndexType keysRange = 0;
      LocalIndexType maxValuesCount = 0;

      __cuda_callable__
      IndexType getAllocationKeysRange( IndexType keysRange ) const;

      // friend class is needed for templated assignment operators
      template< typename Index_, typename Device_, typename LocalIndex_, int SliceSize_ >
      friend class EllpackIndexMultimap;
};

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
std::ostream& operator << ( std::ostream& str, const EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >& multimap );

} // namespace Multimaps
} // namespace Containers
} // namespace TNL

#include <TNL/Containers/Multimaps/EllpackIndexMultimap.hpp>
+0 −321
Original line number Diff line number Diff line
/***************************************************************************
                          EllpackIndexMultimap_impl.h  -  description
                             -------------------
    begin                : Sep 9, 2015
    copyright            : (C) 2015 by Tomas Oberhuber et al.
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#pragma once 

#include <TNL/Containers/Multimaps/EllpackIndexMultimap.h>

namespace TNL {
namespace Containers {
namespace Multimaps {

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
   template< typename Device_ >
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
EllpackIndexMultimap( const EllpackIndexMultimap< Index, Device_, LocalIndex, SliceSize >& other )
{
   operator=( other );
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
   template< typename Device_ >
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >&
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
operator=( const EllpackIndexMultimap< Index, Device_, LocalIndex, SliceSize >& other )
{
   values = other.values;
   valuesCounts = other.valuesCounts;
   keysRange = other.keysRange;
   maxValuesCount = other.maxValuesCount;
   return *this;
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
void
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
setKeysRange( const IndexType& keysRange )
{
   TNL_ASSERT( keysRange >= 0, );
   this->keysRange = keysRange;
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
__cuda_callable__
const Index
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
getKeysRange() const
{
   return this->keysRange;
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
void
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
allocate( const LocalIndexType& maxValuesCount )
{
   TNL_ASSERT( maxValuesCount >= 0, );
   this->maxValuesCount = maxValuesCount;
   const IndexType ldSize = getAllocationKeysRange( this->getKeysRange() );
   this->values.setSize( ldSize * this->maxValuesCount );
   this->valuesCounts.setSize( this->getKeysRange() );
   if( this->valuesCounts.getSize() > 0 )
      this->valuesCounts.setValue( maxValuesCount );

   // extra cost at initialization, which allows to have much simpler operator==
   if( this->values.getSize() > 0 )
      values.setValue( 0 );
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
void
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
allocate( const ValuesAllocationVectorType& valuesCounts )
{
   TNL_ASSERT( valuesCounts.getSize() == this->keysRange,
               std::cerr << "valuesCounts.getSize() =  " << valuesCounts.getSize()
                         << "this->keysRange = " << this->keysRange
                         << std::endl; );
   this->maxValuesCount = max( valuesCounts );
 
   TNL_ASSERT( this->maxValuesCount >= 0,
               std::cerr << "this->maxValuesCount = " << this->maxValuesCount << std::endl; );
   const IndexType ldSize = getAllocationKeysRange( this->getKeysRange() );
   this->values.setSize( ldSize * this->maxValuesCount );
   this->valuesCounts.setSize( this->getKeysRange() );
   this->valuesCounts = valuesCounts;

   // extra cost at initialization, which allows to have much simpler operator==
   if( this->values.getSize() > 0 )
      values.setValue( 0 );
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
   template< typename Device_, int SliceSize_ >
void
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
setLike( const EllpackIndexMultimap< Index, Device_, LocalIndex, SliceSize_ >& other )
{
   const IndexType ldSize = getAllocationKeysRange( other.getKeysRange() );
   values.setSize( ldSize * other.maxValuesCount );
   valuesCounts.setLike( other.valuesCounts );
   valuesCounts = other.valuesCounts;
   keysRange = other.keysRange;
   maxValuesCount = other.maxValuesCount;

   // extra cost at initialization, which allows to have much simpler operator==
   if( this->values.getSize() > 0 )
      values.setValue( 0 );
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
__cuda_callable__
typename EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::ValuesAccessorType
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
getValues( const IndexType& inputIndex )
{
   TNL_ASSERT( inputIndex < this->getKeysRange(),
               std::cerr << "inputIndex = " << inputIndex << std::endl
                         << "this->getKeysRange() = " << this->getKeysRange()
                         << std::endl; );
   TNL_ASSERT( getAllocationKeysRange( this->getKeysRange() ) * this->maxValuesCount == this->values.getSize() && this->getKeysRange() == this->valuesCounts.getSize(),
               std::cerr << "The map has not been reallocated after calling setKeysRange()." << std::endl
                         << "this->getKeysRange() = " << this->getKeysRange() << std::endl
                         << "this->maxValuesCount = " << this->maxValuesCount << std::endl
                         << "this->values.getSize() = " << this->values.getSize() << std::endl
                         << "this->valuesCounts.getSize() = " << this->valuesCounts.getSize() << std::endl; );
   const IndexType sliceIdx = inputIndex / SliceSize;
   const IndexType sliceOffset = sliceIdx * SliceSize * this->maxValuesCount;
   const IndexType offset = sliceOffset + inputIndex - sliceIdx * SliceSize;
   return ValuesAccessorType( &this->values[ offset ], &this->valuesCounts[ inputIndex ], this->maxValuesCount );
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
__cuda_callable__
typename EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::ConstValuesAccessorType
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
getValues( const IndexType& inputIndex ) const
{
   TNL_ASSERT( inputIndex < this->getKeysRange(),
              std::cerr << "inputIndex = " << inputIndex << std::endl
                        << "this->getKeysRange() = " << this->getKeysRange()
                        << std::endl; );
   TNL_ASSERT( getAllocationKeysRange( this->getKeysRange() ) * this->maxValuesCount == this->values.getSize() && this->getKeysRange() == this->valuesCounts.getSize(),
              std::cerr << "The map has not been reallocated after calling setKeysRange()." << std::endl
                        << "this->getKeysRange() = " << this->getKeysRange() << std::endl
                        << "this->maxValuesCount = " << this->maxValuesCount << std::endl
                        << "this->values.getSize() = " << this->values.getSize() << std::endl
                        << "this->valuesCounts.getSize() = " << this->valuesCounts.getSize() << std::endl; );
   const IndexType sliceIdx = inputIndex / SliceSize;
   const IndexType sliceOffset = sliceIdx * SliceSize * this->maxValuesCount;
   const IndexType offset = sliceOffset + inputIndex - sliceIdx * SliceSize;
   return ConstValuesAccessorType( &this->values[ offset ], &this->valuesCounts[ inputIndex ], this->maxValuesCount );
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
__cuda_callable__
LocalIndex
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
getValuesCount( const IndexType& inputIndex ) const
{
   return valuesCounts[ inputIndex ];
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
__cuda_callable__
Index
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
getValue( const IndexType& inputIndex, const LocalIndexType& portIndex ) const
{
   TNL_ASSERT( inputIndex < this->getKeysRange(),
              std::cerr << "inputIndex = " << inputIndex << std::endl
                        << "this->getKeysRange() = " << this->getKeysRange()
                        << std::endl; );
   TNL_ASSERT( getAllocationKeysRange( this->getKeysRange() ) * this->maxValuesCount == this->values.getSize() && this->getKeysRange() == this->valuesCounts.getSize(),
              std::cerr << "The map has not been reallocated after calling setKeysRange()." << std::endl
                        << "this->getKeysRange() = " << this->getKeysRange() << std::endl
                        << "this->maxValuesCount = " << this->maxValuesCount << std::endl
                        << "this->values.getSize() = " << this->values.getSize() << std::endl
                        << "this->valuesCounts.getSize() = " << this->valuesCounts.getSize() << std::endl; );
   const IndexType sliceIdx = inputIndex / SliceSize;
   const IndexType sliceOffset = sliceIdx * SliceSize * this->maxValuesCount;
   const IndexType offset = sliceOffset + inputIndex - sliceIdx * SliceSize;
   return this->values[ offset + portIndex * SliceSize ];
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
bool
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
operator==( const EllpackIndexMultimap& other ) const
{
//   if( ! ( this->keysRange == other.keysRange &&
//           this->maxValuesCount == other.maxValuesCount &&
//           this->valuesCounts == other.valuesCounts ) )
//      return false;
//   // compare values for each key separately - the sizes may vary
//   for( IndexType i = 0; i < this->keysRange; i++ )
//      if( this->getValues( i ) != other.getValues( i ) )
//         return false;
//   return true;

   // we assume that invalid entries in the ellpack format are always 0
   return this->keysRange == other.keysRange &&
          this->maxValuesCount == other.maxValuesCount &&
          this->valuesCounts == other.valuesCounts &&
          this->values == other.values;
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
void
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
save( File& file ) const
{
   Object::save( file );
   file.save( &this->keysRange );
   file.save( &this->maxValuesCount );
   file << this->values << this->valuesCounts;
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
void
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
load( File& file )
{
   Object::load( file );
   file.load( &this->keysRange );
   file.load( &this->maxValuesCount );
   file >> this->values >> this->valuesCounts;
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
void
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
print( std::ostream& str ) const
{
   str << "[ ";
   if( this->getKeysRange() > 0 )
   {
      str << this->getValues( 0 );
      for( Index i = 1; i < this->getKeysRange(); i++ )
         str << ",\n  " << this->getValues( i );
   }
   str << " ]";
}

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
__cuda_callable__
Index
EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >::
getAllocationKeysRange( IndexType keysRange ) const
{
   return SliceSize * roundUpDivision( keysRange, SliceSize );
}


template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
std::ostream& operator << ( std::ostream& str, const EllpackIndexMultimap< Index, Device, LocalIndex, SliceSize >& multimap )
{
   multimap.print( str );
   return str;
}

} // namespace Multimaps
} // namespace Containers
} // namespace TNL
+0 −121
Original line number Diff line number Diff line
/***************************************************************************
                          EllpackIndexMultimapValues.h  -  description
                             -------------------
    begin                : Sep 10, 2015
    copyright            : (C) 2015 by Tomas Oberhuber et al.
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#pragma once

#include <type_traits>
#include <ostream>

#include <TNL/Cuda/CudaCallable.h>

namespace TNL {
namespace Containers {
namespace Multimaps {

template< typename Index,
          typename Device,
          typename LocalIndex,
          int SliceSize >
class EllpackIndexMultimap;

template< typename Index,
          typename Device,
          typename LocalIndex,
          int step = 1 >
class EllpackIndexMultimapValues
{
   public:
      using DeviceType     = Device;
      using IndexType      = Index;
      using LocalIndexType = LocalIndex;
      using NetworkType    = EllpackIndexMultimap< IndexType, DeviceType, LocalIndexType, step >;

      __cuda_callable__
      EllpackIndexMultimapValues();

      __cuda_callable__
      EllpackIndexMultimapValues( EllpackIndexMultimapValues&& other );

      __cuda_callable__
      EllpackIndexMultimapValues& operator=( const EllpackIndexMultimapValues& );

      // converting assignment, needed for 'const int' -> 'int' etc.
      template< typename Index_, typename LocalIndex_, int step_ >
      __cuda_callable__
      EllpackIndexMultimapValues& operator=( const EllpackIndexMultimapValues< Index_, Device, LocalIndex_, step_ >& other );

      __cuda_callable__
      EllpackIndexMultimapValues& operator=( EllpackIndexMultimapValues&& other );

      __cuda_callable__
      void bind( const EllpackIndexMultimapValues& other );

      __cuda_callable__
      void setSize( const LocalIndexType& portsCount );

      __cuda_callable__
      LocalIndexType getSize() const;

      __cuda_callable__
      LocalIndexType getAllocatedSize() const;

      __cuda_callable__
      void setValue( const LocalIndexType& portIndex,
                     const IndexType& value );

      __cuda_callable__
      IndexType getValue( const LocalIndexType& portIndex ) const;

      __cuda_callable__
      IndexType& operator[]( const LocalIndexType& portIndex );

      __cuda_callable__
      const IndexType& operator[]( const LocalIndexType& portIndex ) const;

      __cuda_callable__
      bool operator==( const EllpackIndexMultimapValues& other ) const;

      __cuda_callable__
      bool operator!=( const EllpackIndexMultimapValues& other ) const;

      void print( std::ostream& str ) const;

   protected:
      using ValuesCountType = typename std::conditional< std::is_const< IndexType >::value,
                                                         std::add_const_t< LocalIndexType >,
                                                         LocalIndexType >::type;

      __cuda_callable__
      EllpackIndexMultimapValues( IndexType* values,
                                  ValuesCountType* valuesCount,
                                  const LocalIndexType& allocatedSize );

      IndexType* values;

      ValuesCountType* valuesCount;

      // TODO: this is useless for a const-accessor (without setSize etc.)
      LocalIndexType allocatedSize;

      friend EllpackIndexMultimap< IndexType, DeviceType, LocalIndexType, step >;
      friend EllpackIndexMultimap< typename std::remove_const< IndexType >::type, DeviceType, LocalIndexType, step >;
};

template< typename Index,
          typename Device,
          typename LocalIndex,
          int step >
std::ostream& operator << ( std::ostream& str, const EllpackIndexMultimapValues< Index, Device, LocalIndex, step >& ports );

} // namespace Multimaps
} // namespace Containers
} // namespace TNL

#include <TNL/Containers/Multimaps/EllpackIndexMultimapValues.hpp>
+0 −293

File deleted.

Preview size limit exceeded, changes collapsed.

+0 −90
Original line number Diff line number Diff line
/***************************************************************************
                          IndexPermutationApplier.h  -  description
                             -------------------
    begin                : Mar 10, 2017
    copyright            : (C) 2017 by Tomas Oberhuber et al.
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#pragma once

#include <TNL/Pointers/DevicePointer.h>
#include <TNL/Algorithms/ParallelFor.h>

namespace TNL {
namespace Containers {
namespace Multimaps {

template< typename Multimap,
          typename PermutationArray >
void permuteMultimapKeys( Multimap& multimap, const PermutationArray& perm )
{
   static_assert( std::is_same< typename Multimap::DeviceType, typename PermutationArray::DeviceType >::value,
                  "The multimap and permutation vector must be stored on the same device." );
   using IndexType = typename Multimap::IndexType;
   using DeviceType = typename Multimap::DeviceType;
   TNL_ASSERT( multimap.getKeysRange() == perm.getSize(),
               std::cerr << "multimap keys range is " << multimap.getKeysRange()
                         << ", permutation size is " << perm.getSize() << std::endl; );

   // create temporary multimap for the permuted data
   Multimap multimapCopy;
   multimapCopy.setLike( multimap );

   // kernel to permute the rows of multimap into multimapCopy
   auto kernel = [] __cuda_callable__
      ( IndexType i,
        const Multimap* multimap,
        Multimap* multimapCopy,
        const typename PermutationArray::ValueType* perm )
   {
      const auto srcValues = multimap->getValues( perm[ i ] );
      auto destValues = multimapCopy->getValues( i );
      destValues = srcValues;
   };

   Pointers::DevicePointer< Multimap > multimapPointer( multimap );
   Pointers::DevicePointer< Multimap > multimapCopyPointer( multimapCopy );

   Algorithms::ParallelFor< DeviceType >::exec( (IndexType) 0, multimap.getKeysRange(),
                                                kernel,
                                                &multimapPointer.template getData< DeviceType >(),
                                                &multimapCopyPointer.template modifyData< DeviceType >(),
                                                perm.getData() );

   // copy the permuted data back into the multimap
   multimap = multimapCopy;
}

template< typename Multimap,
          typename PermutationArray >
void permuteMultimapValues( Multimap& multimap, const PermutationArray& iperm )
{
   static_assert( std::is_same< typename Multimap::DeviceType, typename PermutationArray::DeviceType >::value,
                  "The multimap and permutation vector must be stored on the same device." );
   using IndexType = typename Multimap::IndexType;
   using DeviceType = typename Multimap::DeviceType;

   // kernel to permute the multimap values
   auto kernel = [] __cuda_callable__
      ( IndexType i,
        Multimap* multimap,
        const typename PermutationArray::ValueType* iperm )
   {
      auto values = multimap->getValues( i );
      for( typename Multimap::LocalIndexType v = 0; v < values.getSize(); v++ )
         values[ v ] = iperm[ values[ v ] ];
   };

   Pointers::DevicePointer< Multimap > multimapPointer( multimap );
   Algorithms::ParallelFor< DeviceType >::exec( (IndexType) 0, multimap.getKeysRange(),
                                                kernel,
                                                &multimapPointer.template modifyData< DeviceType >(),
                                                iperm.getData() );
}

} // namespace Multimaps
} // namespace Containers
} // namespace TNL
Loading