LCOV - code coverage report
Current view: top level - src/Field - BareField.hpp (source / functions) Coverage Total Hit
Test: final_report.info Lines: 89.2 % 83 74
Test Date: 2025-07-18 17:15:09 Functions: 83.2 % 1128 938

            Line data    Source code
       1              : //
       2              : // Class BareField
       3              : //   A BareField consists of multple LFields and represents a field.
       4              : //
       5              : #include "Ippl.h"
       6              : 
       7              : #include <Kokkos_ReductionIdentity.hpp>
       8              : #include <cstdlib>
       9              : #include <limits>
      10              : #include <map>
      11              : #include <utility>
      12              : 
      13              : #include "Communicate/DataTypes.h"
      14              : 
      15              : #include "Utility/Inform.h"
      16              : #include "Utility/IpplInfo.h"
      17              : namespace Kokkos {
      18              :     template <typename T, unsigned Dim>
      19              :     struct reduction_identity<ippl::Vector<T, Dim>> {
      20              :         KOKKOS_FORCEINLINE_FUNCTION static ippl::Vector<T, Dim> sum() {
      21           56 :             return ippl::Vector<T, Dim>(0);
      22              :         }
      23              :         KOKKOS_FORCEINLINE_FUNCTION static ippl::Vector<T, Dim> prod() {
      24              :             return ippl::Vector<T, Dim>(1);
      25              :         }
      26              :         KOKKOS_FORCEINLINE_FUNCTION static ippl::Vector<T, Dim> min() {
      27           48 :             return ippl::Vector<T, Dim>(std::numeric_limits<T>::infinity());
      28              :         }
      29              :         KOKKOS_FORCEINLINE_FUNCTION static ippl::Vector<T, Dim> max() {
      30           48 :             return ippl::Vector<T, Dim>(-std::numeric_limits<T>::infinity());
      31              :         }
      32              :     };
      33              : }  // namespace Kokkos
      34              : 
      35              : namespace KokkosCorrection {
      36              :     template <typename Scalar, class Space = Kokkos::HostSpace>
      37              :     struct Max : Kokkos::Max<Scalar, Space> {
      38              :         using Super      = Kokkos::Max<Scalar, Space>;
      39              :         using value_type = typename Super::value_type;
      40           48 :         KOKKOS_INLINE_FUNCTION Max(value_type& vref)
      41           48 :             : Super(vref) {}
      42              :         KOKKOS_INLINE_FUNCTION void join(value_type& dest, const value_type& src) const {
      43              :             using ippl::max;
      44              :             using Kokkos::max;
      45              :             dest = max(dest, src);
      46              :         }
      47              :     };
      48              :     template <typename Scalar, class Space = Kokkos::HostSpace>
      49              :     struct Min : Kokkos::Min<Scalar, Space> {
      50              :         using Super      = Kokkos::Min<Scalar, Space>;
      51              :         using value_type = typename Super::value_type;
      52           48 :         KOKKOS_INLINE_FUNCTION Min(value_type& vref)
      53           48 :             : Super(vref) {}
      54              :         KOKKOS_INLINE_FUNCTION void join(value_type& dest, const value_type& src) const {
      55              :             using ippl::min;
      56              :             using Kokkos::min;
      57              :             dest = min(dest, src);
      58              :         }
      59              :     };
      60              :     template <typename Scalar, class Space = Kokkos::HostSpace>
      61              :     struct Sum : Kokkos::Sum<Scalar, Space> {
      62              :         using Super      = Kokkos::Sum<Scalar, Space>;
      63              :         using value_type = typename Super::value_type;
      64          168 :         KOKKOS_INLINE_FUNCTION Sum(value_type& vref)
      65          168 :             : Super(vref) {}
      66              :         KOKKOS_INLINE_FUNCTION void join(value_type& dest, const value_type& src) const {
      67              :             dest += src;
      68              :         }
      69              :     };
      70              :     template <typename Scalar, class Space = Kokkos::HostSpace>
      71              :     struct Prod : Kokkos::Prod<Scalar, Space> {
      72              :         using Super      = Kokkos::Prod<Scalar, Space>;
      73              :         using value_type = typename Super::value_type;
      74           24 :         KOKKOS_INLINE_FUNCTION Prod(value_type& vref)
      75           24 :             : Super(vref) {}
      76              :         KOKKOS_INLINE_FUNCTION void join(value_type& dest, const value_type& src) const {
      77              :             dest *= src;
      78              :         }
      79              :     };
      80              : }  // namespace KokkosCorrection
      81              : 
      82              : namespace ippl {
      83              :     namespace detail {
      84              :         template <typename T, unsigned Dim, class... ViewArgs>
      85              :         struct isExpression<BareField<T, Dim, ViewArgs...>> : std::true_type {};
      86              :     }  // namespace detail
      87              : 
      88              :     template <typename T, unsigned Dim, class... ViewArgs>
      89           48 :     BareField<T, Dim, ViewArgs...>::BareField()
      90           48 :         : nghost_m(1)
      91           48 :         , layout_m(nullptr) {}
      92              : 
      93              :     template <typename T, unsigned Dim, class... ViewArgs>
      94           24 :     BareField<T, Dim, ViewArgs...> BareField<T, Dim, ViewArgs...>::deepCopy() const {
      95           24 :         BareField<T, Dim, ViewArgs...> copy(*layout_m, nghost_m);
      96           24 :         Kokkos::deep_copy(copy.dview_m, dview_m);
      97           24 :         return copy;
      98            0 :     }
      99              : 
     100              :     template <typename T, unsigned Dim, class... ViewArgs>
     101         1508 :     BareField<T, Dim, ViewArgs...>::BareField(Layout_t& l, int nghost)
     102         1508 :         : nghost_m(nghost)
     103              :         //     , owned_m(0)
     104         1508 :         , layout_m(&l) {
     105         1508 :         setup();
     106         1508 :     }
     107              : 
     108              :     template <typename T, unsigned Dim, class... ViewArgs>
     109           48 :     void BareField<T, Dim, ViewArgs...>::initialize(Layout_t& l, int nghost) {
     110           48 :         if (layout_m == 0) {
     111           48 :             layout_m = &l;
     112           48 :             nghost_m = nghost;
     113           48 :             setup();
     114              :         }
     115           48 :     }
     116              : 
     117              :     // ML
     118              :     template <typename T, unsigned Dim, class... ViewArgs>
     119           96 :     void BareField<T, Dim, ViewArgs...>::updateLayout(Layout_t& l, int nghost) {
     120              :         // std::cout << "Got in BareField::updateLayout()" << std::endl;
     121           96 :         layout_m = &l;
     122           96 :         nghost_m = nghost;
     123           96 :         setup();
     124           96 :     }
     125              : 
     126              :     template <typename T, unsigned Dim, class... ViewArgs>
     127         1652 :     void BareField<T, Dim, ViewArgs...>::setup() {
     128         1652 :         owned_m = layout_m->getLocalNDIndex();
     129              : 
     130         4956 :         auto resize = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
     131         1652 :             this->resize((owned_m[Idx].length() + 2 * nghost_m)...);
     132              :         };
     133         1652 :         resize(std::make_index_sequence<Dim>{});
     134         1652 :     }
     135              : 
     136              :     template <typename T, unsigned Dim, class... ViewArgs>
     137              :     template <typename... Args>
     138         1652 :     void BareField<T, Dim, ViewArgs...>::resize(Args... args) {
     139         1652 :         Kokkos::resize(dview_m, args...);
     140         1652 :     }
     141              : 
     142              :     template <typename T, unsigned Dim, class... ViewArgs>
     143          292 :     void BareField<T, Dim, ViewArgs...>::fillHalo() {
     144          292 :         if (layout_m->comm.size() > 1) {
     145          292 :             halo_m.fillHalo(dview_m, layout_m);
     146              :         }
     147          292 :         if (layout_m->isAllPeriodic_m) {
     148              :             using Op = typename detail::HaloCells<T, Dim, ViewArgs...>::assign;
     149            0 :             halo_m.template applyPeriodicSerialDim<Op>(dview_m, layout_m, nghost_m);
     150              :         }
     151          292 :     }
     152              : 
     153              :     template <typename T, unsigned Dim, class... ViewArgs>
     154          140 :     void BareField<T, Dim, ViewArgs...>::accumulateHalo() {
     155          140 :         if (layout_m->comm.size() > 1) {
     156          140 :             halo_m.accumulateHalo(dview_m, layout_m);
     157              :         }
     158          140 :         if (layout_m->isAllPeriodic_m) {
     159              :             using Op = typename detail::HaloCells<T, Dim, ViewArgs...>::rhs_plus_assign;
     160           72 :             halo_m.template applyPeriodicSerialDim<Op>(dview_m, layout_m, nghost_m);
     161              :         }
     162          140 :     }
     163              : 
     164              :     template <typename T, unsigned Dim, class... ViewArgs>
     165            8 :     void BareField<T, Dim, ViewArgs...>::accumulateHalo_noghost(int nghost) {
     166            8 :         if (layout_m->comm.size() > 1) {
     167            8 :             halo_m.accumulateHalo_noghost(dview_m, layout_m, nghost);
     168              :         }
     169            8 :     }
     170              : 
     171              :     template <typename T, unsigned Dim, class... ViewArgs>
     172          692 :     BareField<T, Dim, ViewArgs...>& BareField<T, Dim, ViewArgs...>::operator=(T x) {
     173              :         using index_array_type = typename RangePolicy<Dim, execution_space>::index_array_type;
     174          692 :         ippl::parallel_for(
     175          692 :             "BareField::operator=(T)", getRangePolicy(dview_m),
     176     46127374 :             KOKKOS_CLASS_LAMBDA(const index_array_type& args) { apply(dview_m, args) = x; });
     177          692 :         return *this;
     178              :     }
     179              : 
     180              :     template <typename T, unsigned Dim, class... ViewArgs>
     181              :     template <typename E, size_t N>
     182          528 :     BareField<T, Dim, ViewArgs...>& BareField<T, Dim, ViewArgs...>::operator=(
     183              :         const detail::Expression<E, N>& expr) {
     184              :         using capture_type     = detail::CapturedExpression<E, N>;
     185          528 :         capture_type expr_     = reinterpret_cast<const capture_type&>(expr);
     186              :         using index_array_type = typename RangePolicy<Dim, execution_space>::index_array_type;
     187          528 :         ippl::parallel_for(
     188          528 :             "BareField::operator=(const Expression&)", getRangePolicy(dview_m, nghost_m),
     189     10042132 :             KOKKOS_CLASS_LAMBDA(const index_array_type& args) {
     190      5020538 :                 apply(dview_m, args) = apply(expr_, args);
     191              :             });
     192          528 :         return *this;
     193              :     }
     194              : 
     195              :     template <typename T, unsigned Dim, class... ViewArgs>
     196            0 :     void BareField<T, Dim, ViewArgs...>::write(std::ostream& out) const {
     197            0 :         Kokkos::fence();
     198            0 :         detail::write<T, Dim>(dview_m, out);
     199            0 :     }
     200              : 
     201              :     template <typename T, unsigned Dim, class... ViewArgs>
     202            0 :     void BareField<T, Dim, ViewArgs...>::write(Inform& inf) const {
     203            0 :         write(inf.getDestination());
     204            0 :     }
     205              : 
     206              : #define DefineReduction(fun, name, op, MPI_Op)                                                 \
     207              :     template <typename T, unsigned Dim, class... ViewArgs>                                     \
     208              :     T BareField<T, Dim, ViewArgs...>::name(int nghost) const {                                 \
     209              :         PAssert_LE(nghost, nghost_m);                                                          \
     210              :         T temp                 = Kokkos::reduction_identity<T>::name();                        \
     211              :         using index_array_type = typename RangePolicy<Dim, execution_space>::index_array_type; \
     212              :         ippl::parallel_reduce(                                                                 \
     213              :             "fun", getRangePolicy(dview_m, nghost_m - nghost),                                 \
     214              :             KOKKOS_CLASS_LAMBDA(const index_array_type& args, T& valL) {                       \
     215              :                 T myVal = apply(dview_m, args);                                                \
     216              :                 op;                                                                            \
     217              :             },                                                                                 \
     218              :             KokkosCorrection::fun<T>(temp));                                                   \
     219              :         T globaltemp = 0.0;                                                                    \
     220              :         layout_m->comm.allreduce(temp, globaltemp, 1, MPI_Op<T>());                            \
     221              :         return globaltemp;                                                                     \
     222              :     }
     223              : 
     224      1671288 :     DefineReduction(Sum, sum, valL += myVal, std::plus)
     225       477528 :     DefineReduction(Max, max, using Kokkos::max; valL = max(valL, myVal), std::greater)
     226       477528 :     DefineReduction(Min, min, using Kokkos::min; valL = min(valL, myVal), std::less)
     227       238752 :     DefineReduction(Prod, prod, valL *= myVal, std::multiplies)
     228              : 
     229              : }  // namespace ippl
        

Generated by: LCOV version 2.0-1