LCOV - code coverage report
Current view: top level - include/kokkos/base - KokkosScalar.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: fa5e60 Lines: 58 58 100.0 %
Date: 2026-06-24 08:03:36 Functions: 127 127 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://www.mooseframework.org
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "KokkosReferenceWrapper.h"
      13             : 
      14             : #include <type_traits>
      15             : #include <utility>
      16             : 
      17             : #ifdef MOOSE_KOKKOS_SCOPE
      18             : #define KOKKOS_SCALAR_FUNCTION KOKKOS_FUNCTION
      19             : #else
      20             : #define KOKKOS_SCALAR_FUNCTION
      21             : #endif
      22             : 
      23             : namespace Moose::Kokkos
      24             : {
      25             : 
      26             : /**
      27             :  * The Kokkos wrapper class that can hold the reference of an arithmetic scalar variable
      28             :  */
      29             : template <typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type>
      30             : class Scalar : public ReferenceWrapper<T>
      31             : {
      32             : public:
      33             :   using value_type = T;
      34             : 
      35             :   /**
      36             :    * Constructor
      37             :    * @param value The writeable reference of the arithmetic scalar variable to store
      38             :    */
      39       59570 :   Scalar(T & value) : ReferenceWrapper<T>(value) {}
      40             :   /**
      41             :    * Copy constructor
      42             :    */
      43     2786309 :   Scalar(const Scalar & object) : ReferenceWrapper<T>(object) {}
      44             : 
      45             :   /**
      46             :    * Assign a scalar value to the underlying host reference
      47             :    * @param value The scalar value to be assigned
      48             :    */
      49           2 :   auto & operator=(const Scalar & value)
      50             :   {
      51           2 :     this->_reference = static_cast<const T &>(value);
      52             : 
      53           2 :     return *this;
      54             :   }
      55             :   /**
      56             :    * Assign an arithmetic value to the underlying host reference
      57             :    * @param value The scalar value to be assigned
      58             :    */
      59             :   template <typename U>
      60         166 :   auto operator=(const U & value) -> decltype(std::declval<T &>() = value, std::declval<Scalar &>())
      61             :   {
      62         166 :     this->_reference = value;
      63             : 
      64         166 :     return *this;
      65             :   }
      66             : 
      67             :   /**
      68             :    * Get the positive value of the scalar
      69             :    * @returns The positive scalar value
      70             :    */
      71           4 :   KOKKOS_SCALAR_FUNCTION auto operator+() const -> decltype(+std::declval<const T &>())
      72             :   {
      73           4 :     return +value();
      74             :   }
      75             :   /**
      76             :    * Get the negated value of the scalar
      77             :    * @returns The negated scalar value
      78             :    */
      79      573986 :   KOKKOS_SCALAR_FUNCTION auto operator-() const -> decltype(-std::declval<const T &>())
      80             :   {
      81      573986 :     return -value();
      82             :   }
      83             : 
      84             :   /**
      85             :    * Add another value to the underlying host reference
      86             :    * @param value The value to add
      87             :    */
      88             :   template <typename U>
      89           4 :   auto operator+=(const U & value)
      90             :       -> decltype(std::declval<T &>() += value, std::declval<Scalar &>())
      91             :   {
      92           4 :     this->_reference += value;
      93             : 
      94           4 :     return *this;
      95             :   }
      96             :   /**
      97             :    * Subtract another value from the underlying host reference
      98             :    * @param value The value to subtract
      99             :    */
     100             :   template <typename U>
     101           2 :   auto operator-=(const U & value)
     102             :       -> decltype(std::declval<T &>() -= value, std::declval<Scalar &>())
     103             :   {
     104           2 :     this->_reference -= value;
     105             : 
     106           2 :     return *this;
     107             :   }
     108             :   /**
     109             :    * Multiply the underlying host reference by another value
     110             :    * @param value The value to multiply by
     111             :    */
     112             :   template <typename U>
     113           2 :   auto operator*=(const U & value)
     114             :       -> decltype(std::declval<T &>() *= value, std::declval<Scalar &>())
     115             :   {
     116           2 :     this->_reference *= value;
     117             : 
     118           2 :     return *this;
     119             :   }
     120             :   /**
     121             :    * Divide the underlying host reference by another value
     122             :    * @param value The value to divide by
     123             :    */
     124             :   template <typename U>
     125           2 :   auto operator/=(const U & value)
     126             :       -> decltype(std::declval<T &>() /= value, std::declval<Scalar &>())
     127             :   {
     128           2 :     this->_reference /= value;
     129             : 
     130           2 :     return *this;
     131             :   }
     132             :   /**
     133             :    * Assign the remainder after division by another value to the underlying host reference
     134             :    * @param value The divisor value
     135             :    */
     136             :   template <typename U>
     137           4 :   auto operator%=(const U & value)
     138             :       -> decltype(std::declval<T &>() %= value, std::declval<Scalar &>())
     139             :   {
     140           4 :     this->_reference %= value;
     141             : 
     142           4 :     return *this;
     143             :   }
     144             : 
     145             :   /**
     146             :    * Prefix increment the underlying host reference
     147             :    * @returns This scalar wrapper
     148             :    */
     149             :   template <typename U = T>
     150           2 :   auto operator++() -> decltype(++std::declval<U &>(), std::declval<Scalar &>())
     151             :   {
     152           2 :     ++this->_reference;
     153             : 
     154           2 :     return *this;
     155             :   }
     156             :   /**
     157             :    * Postfix increment the underlying host reference
     158             :    * @returns The previous scalar value
     159             :    */
     160             :   template <typename U = T>
     161           2 :   auto operator++(int) -> decltype(std::declval<U &>()++)
     162             :   {
     163           2 :     return this->_reference++;
     164             :   }
     165             :   /**
     166             :    * Prefix decrement the underlying host reference
     167             :    * @returns This scalar wrapper
     168             :    */
     169             :   template <typename U = T>
     170           2 :   auto operator--() -> decltype(--std::declval<U &>(), std::declval<Scalar &>())
     171             :   {
     172           2 :     --this->_reference;
     173             : 
     174           2 :     return *this;
     175             :   }
     176             :   /**
     177             :    * Postfix decrement the underlying host reference
     178             :    * @returns The previous scalar value
     179             :    */
     180             :   template <typename U = T>
     181           2 :   auto operator--(int) -> decltype(std::declval<U &>()--)
     182             :   {
     183           2 :     return this->_reference--;
     184             :   }
     185             : 
     186             :   /**
     187             :    * Add another value to this scalar
     188             :    * @param value The value to add
     189             :    * @returns The sum
     190             :    */
     191             :   template <typename U>
     192      159543 :   KOKKOS_SCALAR_FUNCTION auto operator+(const U & value) const
     193             :       -> decltype(std::declval<const T &>() + value)
     194             :   {
     195      159543 :     return this->value() + value;
     196             :   }
     197             :   /**
     198             :    * Subtract another value from this scalar
     199             :    * @param value The value to subtract
     200             :    * @returns The difference
     201             :    */
     202             :   template <typename U>
     203         178 :   KOKKOS_SCALAR_FUNCTION auto operator-(const U & value) const
     204             :       -> decltype(std::declval<const T &>() - value)
     205             :   {
     206         178 :     return this->value() - value;
     207             :   }
     208             :   /**
     209             :    * Multiply this scalar by another value
     210             :    * @param value The value to multiply by
     211             :    * @returns The product
     212             :    */
     213             :   template <typename U>
     214    17554932 :   KOKKOS_SCALAR_FUNCTION auto operator*(const U & value) const
     215             :       -> decltype(std::declval<const T &>() * value)
     216             :   {
     217    17554932 :     return this->value() * value;
     218             :   }
     219             :   /**
     220             :    * Divide this scalar by another value
     221             :    * @param value The value to divide by
     222             :    * @returns The quotient
     223             :    */
     224             :   template <typename U>
     225          28 :   KOKKOS_SCALAR_FUNCTION auto operator/(const U & value) const
     226             :       -> decltype(std::declval<const T &>() / value)
     227             :   {
     228          28 :     return this->value() / value;
     229             :   }
     230             :   /**
     231             :    * Get the remainder after division by another value
     232             :    * @param value The divisor value
     233             :    * @returns The remainder
     234             :    */
     235             :   template <typename U>
     236          14 :   KOKKOS_SCALAR_FUNCTION auto operator%(const U & value) const
     237             :       -> decltype(std::declval<const T &>() % value)
     238             :   {
     239          14 :     return this->value() % value;
     240             :   }
     241             : 
     242             : private:
     243    18288685 :   KOKKOS_SCALAR_FUNCTION const T & value() const { return static_cast<const T &>(*this); }
     244             : };
     245             : 
     246             : template <typename>
     247             : struct is_scalar : std::false_type
     248             : {
     249             : };
     250             : 
     251             : template <typename T, typename Enable>
     252             : struct is_scalar<Scalar<T, Enable>> : std::true_type
     253             : {
     254             : };
     255             : 
     256             : template <typename T,
     257             :           typename U,
     258             :           typename = typename std::enable_if<!is_scalar<typename std::decay<T>::type>::value>::type>
     259             : KOKKOS_SCALAR_FUNCTION auto
     260      131313 : operator+(const T & left, const Scalar<U> & right) -> decltype(left + static_cast<const U &>(right))
     261             : {
     262      131313 :   return left + static_cast<const U &>(right);
     263             : }
     264             : 
     265             : template <typename T,
     266             :           typename U,
     267             :           typename = typename std::enable_if<!is_scalar<typename std::decay<T>::type>::value>::type>
     268             : KOKKOS_SCALAR_FUNCTION auto
     269         490 : operator-(const T & left, const Scalar<U> & right) -> decltype(left - static_cast<const U &>(right))
     270             : {
     271         490 :   return left - static_cast<const U &>(right);
     272             : }
     273             : 
     274             : template <typename T,
     275             :           typename U,
     276             :           typename = typename std::enable_if<!is_scalar<typename std::decay<T>::type>::value>::type>
     277             : KOKKOS_SCALAR_FUNCTION auto
     278     6591604 : operator*(const T & left, const Scalar<U> & right) -> decltype(left * static_cast<const U &>(right))
     279             : {
     280     6591604 :   return left * static_cast<const U &>(right);
     281             : }
     282             : 
     283             : template <typename T,
     284             :           typename U,
     285             :           typename = typename std::enable_if<!is_scalar<typename std::decay<T>::type>::value>::type>
     286             : KOKKOS_SCALAR_FUNCTION auto
     287          28 : operator/(const T & left, const Scalar<U> & right) -> decltype(left / static_cast<const U &>(right))
     288             : {
     289          28 :   return left / static_cast<const U &>(right);
     290             : }
     291             : 
     292             : template <typename T,
     293             :           typename U,
     294             :           typename = typename std::enable_if<!is_scalar<typename std::decay<T>::type>::value>::type>
     295             : KOKKOS_SCALAR_FUNCTION auto
     296          14 : operator%(const T & left, const Scalar<U> & right) -> decltype(left % static_cast<const U &>(right))
     297             : {
     298          14 :   return left % static_cast<const U &>(right);
     299             : }
     300             : 
     301             : template <typename T>
     302             : struct ArrayDeepCopy<Scalar<T>>
     303             : {
     304             :   static constexpr bool value = true;
     305             : };
     306             : 
     307             : // Mimic MOOSE convention
     308             : using PostprocessorValue = Scalar<const PostprocessorValue>;
     309             : 
     310             : } // namespace Moose::Kokkos

Generated by: LCOV version 1.14