Commit 4596dc2a authored by Tomáš Oberhuber's avatar Tomáš Oberhuber
Browse files

Refuctoring Functional.h

parent 30139b7c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ maximumNorm( const Vector< double, Device >& v )
   auto view = v.getConstView();

   auto fetch = [=] __cuda_callable__ ( int i ) { return abs( view[ i ] ); };
   return reduceWithArgument< Device >( 0, view.getSize(), fetch, TNL::MaxWithArg<>{} );
   return reduceWithArgument< Device >( 0, view.getSize(), fetch, TNL::MaxWithArg{} );
}

int main( int argc, char* argv[] )
+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ double scalarProduct( const Vector< double, Device >& u, const Vector< double, D
   return reduce< Device >(
      0, v_view.getSize(),
      [=] __cuda_callable__ ( int i ) { return u_view[ i ] * v_view[ i ]; },
      TNL::Plus<>{} );
      TNL::Plus{} );
}

int main( int argc, char* argv[] )
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ double sum( const Vector< double, Device >& v )
    * Finally we call the templated function Reduction and pass number of elements to reduce,
    * lambda defined above and functional representing the reduction operation.
    */
   return reduce< Device >( 0, view.getSize(), fetch, TNL::Plus<>{} );
   return reduce< Device >( 0, view.getSize(), fetch, TNL::Plus{} );
}

int main( int argc, char* argv[] )
+12 −12
Original line number Diff line number Diff line
@@ -170,17 +170,17 @@ This example also shows more compact how to evoke the function `reduce` (lines 1
In \ref TNL/Functionals.h you may find probably all operations that can be reasonably used for reduction:

| Functional                      | Reduction operation      |
|-----------------------------------|--------------------------|
| \ref TNL::Plus<>                  | Sum                      |
| \ref TNL::Multiplies<>            | Product                  |
| \ref TNL::Min<>                   | Minimum                  |
| \ref TNL::Max<>                   | Maximum                  |
| \ref TNL::MinWithArg<>            | Minimum with argument    |
| \ref TNL::MaxWithArg<>            | Maximum with argument    |
| \ref TNL::LogicalAnd<>            | Logical AND              |
| \ref TNL::LogicalOr<>             | Logical OR               |
| \ref TNL::BitAnd<>                | Bit AND                  |
| \ref TNL::BitOr<>                 | Bit OR                   |
|---------------------------------|--------------------------|
| \ref TNL::Plus                  | Sum                      |
| \ref TNL::Multiplies            | Product                  |
| \ref TNL::Min                   | Minimum                  |
| \ref TNL::Max                   | Maximum                  |
| \ref TNL::MinWithArg            | Minimum with argument    |
| \ref TNL::MaxWithArg            | Maximum with argument    |
| \ref TNL::LogicalAnd            | Logical AND              |
| \ref TNL::LogicalOr             | Logical OR               |
| \ref TNL::BitAnd                | Bit AND                  |
| \ref TNL::BitOr                 | Bit OR                   |

## Flexible scan

+26 −226
Original line number Diff line number Diff line
@@ -10,164 +10,68 @@

#pragma once

#include <functional>
#include <algorithm>
#include <limits>

namespace TNL {

/**
 * \brief Replacement of std::plus optimized for use with \ref TNL::Algorithms::reduce.
 *
 * \tparam Value is data type.
 */
template< typename Value = void >
struct Plus
{
   using ValueType = Value;

   static constexpr Value getIdempotent() { return ( Value ) 0; };

   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs + rhs; }
};

/**
 * \brief Replacement of std::plus optimized for use with \ref TNL::Algorithms::reduce.
 * \brief Extension of std::plus for use with \ref TNL::Algorithms::reduce.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct Plus< void >
struct Plus : public std::plus< void >
{
   template< typename T >
   static constexpr T getIdempotent() { return ( T ) 0; };

   template< typename T >
   constexpr T operator()( const T& lhs, const T& rhs ) const { return lhs + rhs; }
};

/**
 * \brief Replacement of std::multiplies optimized for use with \ref TNL::Algorithms::reduce.
 *
 * \tparam Value is data type.
 */
template< typename Value = void >
struct Multiplies
{
   using ValueType = Value;

   static constexpr ValueType idempotent = 1;

   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs * rhs; }
};

/**
 * \brief Replacement of std::multiplies optimized for use with \ref TNL::Algorithms::reduce.
 * \brief Extension of std::multiplies for use with \ref TNL::Algorithms::reduce.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct Multiplies< void >
struct Multiplies : public std::multiplies< void >
{
   template< typename T >
   static constexpr T getIdempotent() { return ( T ) 1; };

   template< typename T >
   constexpr T operator()( const T& lhs, const T& rhs ) const { return lhs * rhs; }
};

/**
 * \brief Replacement of std::min optimized for use with \ref TNL::Algorithms::reduce.
 *
 * \tparam Value is data type.
 */
template< typename Value = void >
struct Min
{
   using ValueType = Value;

   static constexpr ValueType idempotent = std::numeric_limits< Value >::max();

   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs < rhs ? lhs : rhs; }
};

/**
 * \brief Replacement of std::min optimized for use with \ref TNL::Algorithms::reduce.
 * \brief Extension of std::min for use with \ref TNL::Algorithms::reduce.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct Min< void >
struct Min
{
   template< typename T >
   static constexpr T getIdempotent() { return std::numeric_limits< T >::max(); };

   template< typename T >
   constexpr T operator()( const T& lhs, const T& rhs ) const { return lhs < rhs ? lhs : rhs; }
};


/**
 * \brief Replacement of std::max optimized for use with \ref TNL::Algorithms::reduce.
 *
 * \tparam Value is data type.
 */
template< typename Value = void >
struct Max
{
   using ValueType = Value;

   static constexpr ValueType idempotent = std::numeric_limits< Value >::min();

   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs > rhs ? lhs : rhs; }
   template< typename Value >
   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs < rhs ? lhs : rhs; }
};

/**
 * \brief Replacement of std::max optimized for use with \ref TNL::Algorithms::reduce.
 * \brief Extension of std::max for use with \ref TNL::Algorithms::reduce.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct Max< void >
struct Max
{
   template< typename T >
   static constexpr T getIdempotent() { return std::numeric_limits< T >::min(); };

   template< typename T >
   constexpr T operator()( const T& lhs, const T& rhs ) const { return lhs > rhs ? lhs : rhs; }
};

/**
 * \brief Replacement of std::min optimized for use with \ref TNL::Algorithms::reduceWithArgument.
 *
 * \tparam Value is data type.
 */
template< typename Value = void, typename Index = void >
struct MinWithArg
{
   using ValueType = Value;

   static constexpr ValueType idempotent = std::numeric_limits< Value >::max();

   constexpr void operator()( Value& lhs, const Value& rhs, Index& lhsIdx, const Index& rhsIdx ) const
   {
      if( lhs > rhs )
      {
         lhs = rhs;
         lhsIdx = rhsIdx;
      }
      else if( lhs == rhs && rhsIdx < lhsIdx )
      {
         lhsIdx = rhsIdx;
      }
   }
   template< typename Value >
   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs > rhs ? lhs : rhs; }
};

/**
 * \brief Replacement of std::min optimized for use with \ref TNL::Algorithms::reduceWithArgument.
 * \brief Extension of std::min for use with \ref TNL::Algorithms::reduceWithArgument.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct MinWithArg< void, void >
struct MinWithArg
{
   template< typename T >
   static constexpr T getIdempotent() { return std::numeric_limits< T >::max(); };
@@ -188,38 +92,11 @@ struct MinWithArg< void, void >
};

/**
 * \brief Replacement of std::max optimized for use with \ref TNL::Algorithms::reduceWithArgument.
 *
 * \tparam Value is data type.
 */
template< typename Value = void, typename Index = void >
struct MaxWithArg
{
   using ValueType = Value;

   static constexpr ValueType idempotent = std::numeric_limits< Value >::min();

   constexpr void operator()( Value& lhs, const Value& rhs, Index& lhsIdx, const Index& rhsIdx ) const
   {
      if( lhs < rhs )
      {
         lhs = rhs;
         lhsIdx = rhsIdx;
      }
      else if( lhs == rhs && rhsIdx < lhsIdx )
      {
         lhsIdx = rhsIdx;
      }
   }
};

/**
 * \brief Replacement of std::max optimized for use with \ref TNL::Algorithms::reduceWithArgument.
 * \brief Extension of std::max for use with \ref TNL::Algorithms::reduceWithArgument.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct MaxWithArg< void, void >
struct MaxWithArg
{
   template< typename T >
   static constexpr T getIdempotent() { return std::numeric_limits< T >::min(); };
@@ -240,124 +117,47 @@ struct MaxWithArg< void, void >
};

/**
 * \brief Replacement of std::logical_and optimized for use with \ref TNL::Algorithms::reduce.
 *
 * \tparam Value is data type.
 */
template< typename Value = void >
struct LogicalAnd
{
   using ValueType = Value;

   static constexpr ValueType idempotent = ( Value ) true;

   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs && rhs; }
};

/**
 * \brief Replacement of std::logical_and optimized for use with \ref TNL::Algorithms::reduce.
 * \brief Extension of std::logical_and for use with \ref TNL::Algorithms::reduce.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct LogicalAnd< void >
struct LogicalAnd : public std::logical_and< void >
{
   template< typename T >
   static constexpr T getIdempotent() { return ( T ) true; };

   template< typename T >
   constexpr T operator()( const T& lhs, const T& rhs ) const { return lhs && rhs; }
};

/**
 * \brief Replacement of std::logical_or optimized for use with \ref TNL::Algorithms::reduce.
 *
 * \tparam Value is data type.
 */
template< typename Value = void >
struct LogicalOr
{
   using ValueType = Value;

   static constexpr ValueType idempotent = ( Value ) false;

   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs || rhs; }
};

/**
 * \brief Replacement of std::logical_or optimized for use with \ref TNL::Algorithms::reduce.
 * \brief Extension of std::logical_or for use with \ref TNL::Algorithms::reduce.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct LogicalOr< void >
struct LogicalOr : public std::logical_or< void >
{
   template< typename T >
   static constexpr T getIdempotent() { return ( T ) false; };

   template< typename T >
   constexpr T operator()( const T& lhs, const T& rhs ) const { return lhs || rhs; }
};


/**
 * \brief Replacement of std::bit_and optimized for use with \ref TNL::Algorithms::reduce.
 *
 * \tparam Value is data type.
 */
template< typename Value = void >
struct BitAnd
{
   using ValueType = Value;

   static constexpr ValueType idempotent = ~static_cast< ValueType >( 0 );

   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs & rhs; }
};

/**
 * \brief Replacement of std::bit_and optimized for use with \ref TNL::Algorithms::reduce.
 * \brief Extension of std::bit_and for use with \ref TNL::Algorithms::reduce.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct BitAnd< void >
struct BitAnd : public std::bit_and< void >
{
   template< typename T >
   static constexpr T getIdempotent() { return ~static_cast< T >( 0 ); };

   template< typename T >
   constexpr T operator()( const T& lhs, const T& rhs ) const { return lhs & rhs; }
};

/**
 * \brief Replacement of std::bit_or optimized for use with \ref TNL::Algorithms::reduce.
 *
 * \tparam Value is data type.
 */
template< typename Value = void >
struct BitOr
{
   using ValueType = Value;

   static constexpr ValueType idempotent =  static_cast< ValueType >( 0 );

   constexpr Value operator()( const Value& lhs, const Value& rhs ) const { return lhs | rhs; }
};

/**
 * \brief Replacement of std::bit_or optimized for use with \ref TNL::Algorithms::reduce.
 * \brief Extension of std::bit_or for use with \ref TNL::Algorithms::reduce.
 *
 * This is specialization for void type. The real type is deduced just when operator() is evoked.
 */
template<>
struct BitOr< void >
struct BitOr : public std::bit_or< void >
{
   template< typename T >
   static constexpr T getIdempotent() { return static_cast< T >( 0 ); };

   template< typename T >
   constexpr T operator()( const T& lhs, const T& rhs ) const { return lhs | rhs; }
};

} // namespace TNL
Loading