Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_MinMax.hpp
1 //@HEADER
2 // ************************************************************************
3 //
4 // Kokkos v. 4.0
5 // Copyright (2022) National Technology & Engineering
6 // Solutions of Sandia, LLC (NTESS).
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 // See https://kokkos.org/LICENSE for license information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //@HEADER
16 
17 #ifndef KOKKOS_MIN_MAX_HPP
18 #define KOKKOS_MIN_MAX_HPP
19 
20 #include <Kokkos_Macros.hpp>
21 #include <Kokkos_Pair.hpp>
22 
23 #include <initializer_list>
24 
25 namespace Kokkos {
26 
27 // max
28 template <class T>
29 constexpr KOKKOS_INLINE_FUNCTION const T& max(const T& a, const T& b) {
30  // Capturing the result of std::max by reference produces a dangling reference
31  // if one of the parameters is a temporary and that parameter is returned.
32  // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)
33  return (a < b) ? b : a;
34 }
35 
36 template <class T, class ComparatorType>
37 constexpr KOKKOS_INLINE_FUNCTION const T& max(const T& a, const T& b,
38  ComparatorType comp) {
39  // Capturing the result of std::max by reference produces a dangling reference
40  // if one of the parameters is a temporary and that parameter is returned.
41  // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)
42  return comp(a, b) ? b : a;
43 }
44 
45 template <class T>
46 KOKKOS_INLINE_FUNCTION constexpr T max(std::initializer_list<T> ilist) {
47  auto first = ilist.begin();
48  auto const last = ilist.end();
49  auto result = *first;
50  if (first == last) return result;
51  while (++first != last) {
52  if (result < *first) result = *first;
53  }
54  return result;
55 }
56 
57 template <class T, class Compare>
58 KOKKOS_INLINE_FUNCTION constexpr T max(std::initializer_list<T> ilist,
59  Compare comp) {
60  auto first = ilist.begin();
61  auto const last = ilist.end();
62  auto result = *first;
63  if (first == last) return result;
64  while (++first != last) {
65  if (comp(result, *first)) result = *first;
66  }
67  return result;
68 }
69 
70 // min
71 template <class T>
72 constexpr KOKKOS_INLINE_FUNCTION const T& min(const T& a, const T& b) {
73  // Capturing the result of std::min by reference produces a dangling reference
74  // if one of the parameters is a temporary and that parameter is returned.
75  // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)
76  return (b < a) ? b : a;
77 }
78 
79 template <class T, class ComparatorType>
80 constexpr KOKKOS_INLINE_FUNCTION const T& min(const T& a, const T& b,
81  ComparatorType comp) {
82  // Capturing the result of std::min by reference produces a dangling reference
83  // if one of the parameters is a temporary and that parameter is returned.
84  // NOLINTNEXTLINE(bugprone-return-const-ref-from-parameter)
85  return comp(b, a) ? b : a;
86 }
87 
88 template <class T>
89 KOKKOS_INLINE_FUNCTION constexpr T min(std::initializer_list<T> ilist) {
90  auto first = ilist.begin();
91  auto const last = ilist.end();
92  auto result = *first;
93  if (first == last) return result;
94  while (++first != last) {
95  if (*first < result) result = *first;
96  }
97  return result;
98 }
99 
100 template <class T, class Compare>
101 KOKKOS_INLINE_FUNCTION constexpr T min(std::initializer_list<T> ilist,
102  Compare comp) {
103  auto first = ilist.begin();
104  auto const last = ilist.end();
105  auto result = *first;
106  if (first == last) return result;
107  while (++first != last) {
108  if (comp(*first, result)) result = *first;
109  }
110  return result;
111 }
112 
113 // minmax
114 template <class T>
115 constexpr KOKKOS_INLINE_FUNCTION auto minmax(const T& a, const T& b) {
116  using return_t = ::Kokkos::pair<const T&, const T&>;
117  return (b < a) ? return_t{b, a} : return_t{a, b};
118 }
119 
120 template <class T, class ComparatorType>
121 constexpr KOKKOS_INLINE_FUNCTION auto minmax(const T& a, const T& b,
122  ComparatorType comp) {
123  using return_t = ::Kokkos::pair<const T&, const T&>;
124  return comp(b, a) ? return_t{b, a} : return_t{a, b};
125 }
126 
127 template <class T>
128 KOKKOS_INLINE_FUNCTION constexpr Kokkos::pair<T, T> minmax(
129  std::initializer_list<T> ilist) {
130  auto first = ilist.begin();
131  auto const last = ilist.end();
132  auto next = first;
133  Kokkos::pair<T, T> result{*first, *first};
134  if (first == last || ++next == last) return result;
135  if (*next < *first)
136  result.first = *next;
137  else
138  result.second = *next;
139  first = next;
140  while (++first != last) {
141  if (++next == last) {
142  if (*first < result.first)
143  result.first = *first;
144  else if (!(*first < result.second))
145  result.second = *first;
146  break;
147  }
148  if (*next < *first) {
149  if (*next < result.first) result.first = *next;
150  if (!(*first < result.second)) result.second = *first;
151  } else {
152  if (*first < result.first) result.first = *first;
153  if (!(*next < result.second)) result.second = *next;
154  }
155  first = next;
156  }
157  return result;
158 }
159 
160 template <class T, class Compare>
161 KOKKOS_INLINE_FUNCTION constexpr Kokkos::pair<T, T> minmax(
162  std::initializer_list<T> ilist, Compare comp) {
163  auto first = ilist.begin();
164  auto const last = ilist.end();
165  auto next = first;
166  Kokkos::pair<T, T> result{*first, *first};
167  if (first == last || ++next == last) return result;
168  if (comp(*next, *first))
169  result.first = *next;
170  else
171  result.second = *next;
172  first = next;
173  while (++first != last) {
174  if (++next == last) {
175  if (comp(*first, result.first))
176  result.first = *first;
177  else if (!comp(*first, result.second))
178  result.second = *first;
179  break;
180  }
181  if (comp(*next, *first)) {
182  if (comp(*next, result.first)) result.first = *next;
183  if (!comp(*first, result.second)) result.second = *first;
184  } else {
185  if (comp(*first, result.first)) result.first = *first;
186  if (!comp(*next, result.second)) result.second = *next;
187  }
188  first = next;
189  }
190  return result;
191 }
192 
193 } // namespace Kokkos
194 
195 #endif
Declaration and definition of Kokkos::pair.
Replacement for std::pair that works on CUDA devices.
Definition: Kokkos_Pair.hpp:44
first_type first
The first element of the pair.
Definition: Kokkos_Pair.hpp:51