1 /* 2 //@HEADER 3 // ************************************************************************ 4 // 5 // Kokkos v. 3.0 6 // Copyright (2020) National Technology & Engineering 7 // Solutions of Sandia, LLC (NTESS). 8 // 9 // Under the terms of Contract DE-NA0003525 with NTESS, 10 // the U.S. Government retains certain rights in this software. 11 // 12 // Redistribution and use in source and binary forms, with or without 13 // modification, are permitted provided that the following conditions are 14 // met: 15 // 16 // 1. Redistributions of source code must retain the above copyright 17 // notice, this list of conditions and the following disclaimer. 18 // 19 // 2. Redistributions in binary form must reproduce the above copyright 20 // notice, this list of conditions and the following disclaimer in the 21 // documentation and/or other materials provided with the distribution. 22 // 23 // 3. Neither the name of the Corporation nor the names of the 24 // contributors may be used to endorse or promote products derived from 25 // this software without specific prior written permission. 26 // 27 // THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY 28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE 31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 // 39 // Questions? Contact Christian R. Trott (crtrott@sandia.gov) 40 // 41 // ************************************************************************ 42 //@HEADER 43 */ 44 45 #include <impl/Kokkos_Utilities.hpp> // type_list 46 47 #include <traits/Kokkos_Traits_fwd.hpp> 48 49 #ifndef KOKKOS_KOKKOS_POLICYTRAITADAPTOR_HPP 50 #define KOKKOS_KOKKOS_POLICYTRAITADAPTOR_HPP 51 52 namespace Kokkos { 53 namespace Impl { 54 55 //============================================================================== 56 // <editor-fold desc="Adapter for replacing/adding a trait"> {{{1 57 58 //------------------------------------------------------------------------------ 59 60 // General strategy: given a TraitSpecification, go through the entries in the 61 // parameter pack of the policy template and find the first one that returns 62 // `true` for the nested `trait_matches_specification` variable template. If 63 // that nested variable template is not found these overloads should be safely 64 // ignored, and the trait can specialize PolicyTraitAdapterImpl to get the 65 // desired behavior. 66 67 //------------------------------------------------------------------------------ 68 69 //------------------------------------------------------------------------------ 70 // <editor-fold desc="PolicyTraitMatcher"> {{{2 71 72 // To handle the WorkTag case, we need more than just a predicate; we need 73 // something that we can default to in the unspecialized case, just like we 74 // do for AnalyzeExecPolicy 75 template <class TraitSpec, class Trait, class Enable = void> 76 struct PolicyTraitMatcher; 77 78 template <class TraitSpec, class Trait> 79 struct PolicyTraitMatcher< 80 TraitSpec, Trait, 81 std::enable_if_t< 82 TraitSpec::template trait_matches_specification<Trait>::value>> 83 : std::true_type {}; 84 85 // </editor-fold> end PolicyTraitMatcher }}}2 86 //------------------------------------------------------------------------------ 87 88 //------------------------------------------------------------------------------ 89 // <editor-fold desc="PolicyTraitAdaptorImpl specializations"> {{{2 90 91 // Matching version, replace the trait 92 template <class TraitSpec, template <class...> class PolicyTemplate, 93 class... ProcessedTraits, class MatchingTrait, 94 class... ToProcessTraits, class NewTrait> 95 struct PolicyTraitAdaptorImpl< 96 TraitSpec, PolicyTemplate, type_list<ProcessedTraits...>, 97 type_list<MatchingTrait, ToProcessTraits...>, NewTrait, 98 std::enable_if_t<PolicyTraitMatcher<TraitSpec, MatchingTrait>::value>> { 99 static_assert(PolicyTraitMatcher<TraitSpec, NewTrait>::value, ""); 100 using type = PolicyTemplate<ProcessedTraits..., NewTrait, ToProcessTraits...>; 101 }; 102 103 // Non-matching version, check the next option 104 template <class TraitSpec, template <class...> class PolicyTemplate, 105 class... ProcessedTraits, class NonMatchingTrait, 106 class... ToProcessTraits, class NewTrait> 107 struct PolicyTraitAdaptorImpl< 108 TraitSpec, PolicyTemplate, type_list<ProcessedTraits...>, 109 type_list<NonMatchingTrait, ToProcessTraits...>, NewTrait, 110 std::enable_if_t<!PolicyTraitMatcher<TraitSpec, NonMatchingTrait>::value>> { 111 using type = typename PolicyTraitAdaptorImpl< 112 TraitSpec, PolicyTemplate, 113 type_list<ProcessedTraits..., NonMatchingTrait>, 114 type_list<ToProcessTraits...>, NewTrait>::type; 115 }; 116 117 // Base case: no matches found; just add the trait to the end of the list 118 template <class TraitSpec, template <class...> class PolicyTemplate, 119 class... ProcessedTraits, class NewTrait> 120 struct PolicyTraitAdaptorImpl<TraitSpec, PolicyTemplate, 121 type_list<ProcessedTraits...>, type_list<>, 122 NewTrait> { 123 static_assert(PolicyTraitMatcher<TraitSpec, NewTrait>::value, ""); 124 using type = PolicyTemplate<ProcessedTraits..., NewTrait>; 125 }; 126 127 // </editor-fold> end PolicyTraitAdaptorImpl specializations }}}2 128 //------------------------------------------------------------------------------ 129 130 template <class TraitSpec, template <class...> class PolicyTemplate, 131 class... Traits, class NewTrait> 132 struct PolicyTraitAdaptor<TraitSpec, PolicyTemplate<Traits...>, NewTrait> 133 : PolicyTraitAdaptorImpl<TraitSpec, PolicyTemplate, type_list<>, 134 type_list<Traits...>, NewTrait> {}; 135 136 // </editor-fold> end Adapter for replacing/adding a trait }}}1 137 //============================================================================== 138 139 //============================================================================== 140 // <editor-fold desc="CRTP Base class for trait specifications"> {{{1 141 142 template <class TraitSpec> 143 struct TraitSpecificationBase { 144 using trait_specification = TraitSpec; 145 template <class Policy, class Trait> 146 using policy_with_trait = 147 typename PolicyTraitAdaptor<TraitSpec, Policy, Trait>::type; 148 }; 149 150 // </editor-fold> end CRTP Base class for trait specifications }}}1 151 //============================================================================== 152 153 } // end namespace Impl 154 } // end namespace Kokkos 155 156 #endif // KOKKOS_KOKKOS_POLICYTRAITADAPTOR_HPP 157