//@HEADER // ************************************************************************ // // Kokkos v. 4.0 // Copyright (2022) National Technology & Engineering // Solutions of Sandia, LLC (NTESS). // // Under the terms of Contract DE-NA0003525 with NTESS, // the U.S. Government retains certain rights in this software. // // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. // See https://kokkos.org/LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //@HEADER #ifndef KOKKOS_OPENMPTARGETREDUCER_HPP #define KOKKOS_OPENMPTARGETREDUCER_HPP #include #include #include "Kokkos_OpenMPTarget_Abort.hpp" namespace Kokkos { namespace Impl { template struct OpenMPTargetReducerWrapper { using value_type = typename Reducer::value_type; // Using a generic unknown Reducer for the OpenMPTarget backend is not // implemented. KOKKOS_INLINE_FUNCTION static void join(value_type&, const value_type&) = delete; KOKKOS_INLINE_FUNCTION static void join(volatile value_type&, const volatile value_type&) = delete; KOKKOS_INLINE_FUNCTION static void init(value_type&) = delete; }; template struct OpenMPTargetReducerWrapper> { public: // Required using value_type = std::remove_cv_t; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest += src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest += src; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val = reduction_identity::sum(); } }; template struct OpenMPTargetReducerWrapper> { public: // Required using value_type = std::remove_cv_t; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest *= src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest *= src; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val = reduction_identity::prod(); } }; template struct OpenMPTargetReducerWrapper> { public: // Required using value_type = std::remove_cv_t; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { if (src < dest) dest = src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { if (src < dest) dest = src; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val = reduction_identity::min(); } }; template struct OpenMPTargetReducerWrapper> { public: // Required using value_type = std::remove_cv_t; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { if (src > dest) dest = src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { if (src > dest) dest = src; } // Required KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val = reduction_identity::max(); } }; template struct OpenMPTargetReducerWrapper> { public: // Required using value_type = std::remove_cv_t; KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest = dest && src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest = dest && src; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val = reduction_identity::land(); } }; template struct OpenMPTargetReducerWrapper> { public: // Required using value_type = std::remove_cv_t; using result_view_type = Kokkos::View; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest = dest || src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest = dest || src; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val = reduction_identity::lor(); } }; template struct OpenMPTargetReducerWrapper> { public: // Required using value_type = std::remove_cv_t; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest = dest & src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest = dest & src; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val = reduction_identity::band(); } }; template struct OpenMPTargetReducerWrapper> { public: // Required using value_type = std::remove_cv_t; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest = dest | src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest = dest | src; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val = reduction_identity::bor(); } }; template struct OpenMPTargetReducerWrapper> { private: using scalar_type = std::remove_cv_t; using index_type = std::remove_cv_t; public: // Required using value_type = ValLocScalar; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { if (src.val < dest.val) dest = src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { if (src.val < dest.val) dest = src; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.val = reduction_identity::min(); val.loc = reduction_identity::min(); } }; template struct OpenMPTargetReducerWrapper> { private: using scalar_type = std::remove_cv_t; using index_type = std::remove_cv_t; public: // Required using value_type = ValLocScalar; KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { if (src.val > dest.val) dest = src; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { if (src.val > dest.val) dest = src; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.val = reduction_identity::max(); val.loc = reduction_identity::min(); } }; template struct OpenMPTargetReducerWrapper> { private: using scalar_type = std::remove_cv_t; public: // Required using value_type = MinMaxScalar; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { if (src.min_val < dest.min_val) { dest.min_val = src.min_val; } if (src.max_val > dest.max_val) { dest.max_val = src.max_val; } } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { if (src.min_val < dest.min_val) { dest.min_val = src.min_val; } if (src.max_val > dest.max_val) { dest.max_val = src.max_val; } } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.max_val = reduction_identity::max(); val.min_val = reduction_identity::min(); } }; template struct OpenMPTargetReducerWrapper> { private: using scalar_type = std::remove_cv_t; using index_type = std::remove_cv_t; public: // Required using value_type = MinMaxLocScalar; // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { if (src.min_val < dest.min_val) { dest.min_val = src.min_val; dest.min_loc = src.min_loc; } if (src.max_val > dest.max_val) { dest.max_val = src.max_val; dest.max_loc = src.max_loc; } } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { if (src.min_val < dest.min_val) { dest.min_val = src.min_val; dest.min_loc = src.min_loc; } if (src.max_val > dest.max_val) { dest.max_val = src.max_val; dest.max_loc = src.max_loc; } } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.max_val = reduction_identity::max(); val.min_val = reduction_identity::min(); val.max_loc = reduction_identity::min(); val.min_loc = reduction_identity::min(); } }; // // specialize for MaxFirstLoc // template struct OpenMPTargetReducerWrapper> { private: using scalar_type = std::remove_cv_t; using index_type = std::remove_cv_t; public: // Required using value_type = ValLocScalar; // WORKAROUND OPENMPTARGET // This pragma omp declare target should not be necessary, but Intel compiler // fails without it #pragma omp declare target KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { if (dest.val < src.val) { dest = src; } else if (!(src.val < dest.val)) { dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc; } } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { if (dest.val < src.val) { dest = src; } else if (!(src.val < dest.val)) { dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc; } } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.val = reduction_identity::max(); val.loc = reduction_identity::min(); } #pragma omp end declare target }; // // specialize for MinFirstLoc // template struct OpenMPTargetReducerWrapper> { private: using scalar_type = std::remove_cv_t; using index_type = std::remove_cv_t; public: // Required using value_type = ValLocScalar; // WORKAROUND OPENMPTARGET // This pragma omp declare target should not be necessary, but Intel compiler // fails without it #pragma omp declare target KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { if (src.val < dest.val) { dest = src; } else if (!(dest.val < src.val)) { dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc; } } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { if (src.val < dest.val) { dest = src; } else if (!(dest.val < src.val)) { dest.loc = (src.loc < dest.loc) ? src.loc : dest.loc; } } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.val = reduction_identity::min(); val.loc = reduction_identity::min(); } #pragma omp end declare target }; // // specialize for MinMaxFirstLastLoc // template struct OpenMPTargetReducerWrapper> { private: using scalar_type = std::remove_cv_t; using index_type = std::remove_cv_t; public: // Required using value_type = MinMaxLocScalar; // WORKAROUND OPENMPTARGET // This pragma omp declare target should not be necessary, but Intel compiler // fails without it #pragma omp declare target // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { if (src.min_val < dest.min_val) { dest.min_val = src.min_val; dest.min_loc = src.min_loc; } else if (!(dest.min_val < src.min_val)) { dest.min_loc = (src.min_loc < dest.min_loc) ? src.min_loc : dest.min_loc; } if (dest.max_val < src.max_val) { dest.max_val = src.max_val; dest.max_loc = src.max_loc; } else if (!(src.max_val < dest.max_val)) { dest.max_loc = (src.max_loc > dest.max_loc) ? src.max_loc : dest.max_loc; } } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { if (src.min_val < dest.min_val) { dest.min_val = src.min_val; dest.min_loc = src.min_loc; } else if (!(dest.min_val < src.min_val)) { dest.min_loc = (src.min_loc < dest.min_loc) ? src.min_loc : dest.min_loc; } if (dest.max_val < src.max_val) { dest.max_val = src.max_val; dest.max_loc = src.max_loc; } else if (!(src.max_val < dest.max_val)) { dest.max_loc = (src.max_loc > dest.max_loc) ? src.max_loc : dest.max_loc; } } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.max_val = reduction_identity::max(); val.min_val = reduction_identity::min(); val.max_loc = reduction_identity::max(); val.min_loc = reduction_identity::min(); } #pragma omp end declare target }; // // specialize for FirstLoc // template struct OpenMPTargetReducerWrapper> { private: using index_type = std::remove_cv_t; public: // Required using value_type = FirstLocScalar; // WORKAROUND OPENMPTARGET // This pragma omp declare target should not be necessary, but Intel compiler // fails without it #pragma omp declare target // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest.min_loc_true = (src.min_loc_true < dest.min_loc_true) ? src.min_loc_true : dest.min_loc_true; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest.min_loc_true = (src.min_loc_true < dest.min_loc_true) ? src.min_loc_true : dest.min_loc_true; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.min_loc_true = reduction_identity::min(); } #pragma omp end declare target }; // // specialize for LastLoc // template struct OpenMPTargetReducerWrapper> { private: using index_type = std::remove_cv_t; public: // Required using value_type = LastLocScalar; // WORKAROUND OPENMPTARGET // This pragma omp declare target should not be necessary, but Intel compiler // fails without it #pragma omp declare target // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest.max_loc_true = (src.max_loc_true > dest.max_loc_true) ? src.max_loc_true : dest.max_loc_true; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest.max_loc_true = (src.max_loc_true > dest.max_loc_true) ? src.max_loc_true : dest.max_loc_true; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.max_loc_true = reduction_identity::max(); } #pragma omp end declare target }; // // specialize for StdIsPartitioned // template struct OpenMPTargetReducerWrapper> { private: using index_type = std::remove_cv_t; public: // Required using value_type = StdIsPartScalar; // WORKAROUND OPENMPTARGET // This pragma omp declare target should not be necessary, but Intel compiler // fails without it #pragma omp declare target // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest.max_loc_true = (dest.max_loc_true < src.max_loc_true) ? src.max_loc_true : dest.max_loc_true; dest.min_loc_false = (dest.min_loc_false < src.min_loc_false) ? dest.min_loc_false : src.min_loc_false; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest.max_loc_true = (dest.max_loc_true < src.max_loc_true) ? src.max_loc_true : dest.max_loc_true; dest.min_loc_false = (dest.min_loc_false < src.min_loc_false) ? dest.min_loc_false : src.min_loc_false; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.max_loc_true = ::Kokkos::reduction_identity::max(); val.min_loc_false = ::Kokkos::reduction_identity::min(); } #pragma omp end declare target }; // // specialize for StdPartitionPoint // template struct OpenMPTargetReducerWrapper> { private: using index_type = std::remove_cv_t; public: // Required using value_type = StdPartPointScalar; // WORKAROUND OPENMPTARGET // This pragma omp declare target should not be necessary, but Intel compiler // fails without it #pragma omp declare target // Required KOKKOS_INLINE_FUNCTION static void join(value_type& dest, const value_type& src) { dest.min_loc_false = (dest.min_loc_false < src.min_loc_false) ? dest.min_loc_false : src.min_loc_false; } KOKKOS_INLINE_FUNCTION static void join(volatile value_type& dest, const volatile value_type& src) { dest.min_loc_false = (dest.min_loc_false < src.min_loc_false) ? dest.min_loc_false : src.min_loc_false; } KOKKOS_INLINE_FUNCTION static void init(value_type& val) { val.min_loc_false = ::Kokkos::reduction_identity::min(); } #pragma omp end declare target }; /* template class OpenMPTargetReducerWrapper { public: const ReducerType& reducer; using value_type = typename ReducerType::value_type; value_type& value; KOKKOS_INLINE_FUNCTION void join(const value_type& upd) { reducer.join(value,upd); } KOKKOS_INLINE_FUNCTION void init(const value_type& upd) { reducer.init(value,upd); } };*/ } // namespace Impl } // namespace Kokkos #endif