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  return (a < b) ? b : a;
31 }
32 
33 template <class T, class ComparatorType>
34 constexpr KOKKOS_INLINE_FUNCTION const T& max(const T& a, const T& b,
35  ComparatorType comp) {
36  return comp(a, b) ? b : a;
37 }
38 
39 template <class T>
40 KOKKOS_INLINE_FUNCTION constexpr T max(std::initializer_list<T> ilist) {
41  auto first = ilist.begin();
42  auto const last = ilist.end();
43  auto result = *first;
44  if (first == last) return result;
45  while (++first != last) {
46  if (result < *first) result = *first;
47  }
48  return result;
49 }
50 
51 template <class T, class Compare>
52 KOKKOS_INLINE_FUNCTION constexpr T max(std::initializer_list<T> ilist,
53  Compare comp) {
54  auto first = ilist.begin();
55  auto const last = ilist.end();
56  auto result = *first;
57  if (first == last) return result;
58  while (++first != last) {
59  if (comp(result, *first)) result = *first;
60  }
61  return result;
62 }
63 
64 // min
65 template <class T>
66 constexpr KOKKOS_INLINE_FUNCTION const T& min(const T& a, const T& b) {
67  return (b < a) ? b : a;
68 }
69 
70 template <class T, class ComparatorType>
71 constexpr KOKKOS_INLINE_FUNCTION const T& min(const T& a, const T& b,
72  ComparatorType comp) {
73  return comp(b, a) ? b : a;
74 }
75 
76 template <class T>
77 KOKKOS_INLINE_FUNCTION constexpr T min(std::initializer_list<T> ilist) {
78  auto first = ilist.begin();
79  auto const last = ilist.end();
80  auto result = *first;
81  if (first == last) return result;
82  while (++first != last) {
83  if (*first < result) result = *first;
84  }
85  return result;
86 }
87 
88 template <class T, class Compare>
89 KOKKOS_INLINE_FUNCTION constexpr T min(std::initializer_list<T> ilist,
90  Compare comp) {
91  auto first = ilist.begin();
92  auto const last = ilist.end();
93  auto result = *first;
94  if (first == last) return result;
95  while (++first != last) {
96  if (comp(*first, result)) result = *first;
97  }
98  return result;
99 }
100 
101 // minmax
102 template <class T>
103 constexpr KOKKOS_INLINE_FUNCTION auto minmax(const T& a, const T& b) {
104  using return_t = ::Kokkos::pair<const T&, const T&>;
105  return (b < a) ? return_t{b, a} : return_t{a, b};
106 }
107 
108 template <class T, class ComparatorType>
109 constexpr KOKKOS_INLINE_FUNCTION auto minmax(const T& a, const T& b,
110  ComparatorType comp) {
111  using return_t = ::Kokkos::pair<const T&, const T&>;
112  return comp(b, a) ? return_t{b, a} : return_t{a, b};
113 }
114 
115 template <class T>
116 KOKKOS_INLINE_FUNCTION constexpr Kokkos::pair<T, T> minmax(
117  std::initializer_list<T> ilist) {
118  auto first = ilist.begin();
119  auto const last = ilist.end();
120  auto next = first;
121  Kokkos::pair<T, T> result{*first, *first};
122  if (first == last || ++next == last) return result;
123  if (*next < *first)
124  result.first = *next;
125  else
126  result.second = *next;
127  first = next;
128  while (++first != last) {
129  if (++next == last) {
130  if (*first < result.first)
131  result.first = *first;
132  else if (!(*first < result.second))
133  result.second = *first;
134  break;
135  }
136  if (*next < *first) {
137  if (*next < result.first) result.first = *next;
138  if (!(*first < result.second)) result.second = *first;
139  } else {
140  if (*first < result.first) result.first = *first;
141  if (!(*next < result.second)) result.second = *next;
142  }
143  first = next;
144  }
145  return result;
146 }
147 
148 template <class T, class Compare>
149 KOKKOS_INLINE_FUNCTION constexpr Kokkos::pair<T, T> minmax(
150  std::initializer_list<T> ilist, Compare comp) {
151  auto first = ilist.begin();
152  auto const last = ilist.end();
153  auto next = first;
154  Kokkos::pair<T, T> result{*first, *first};
155  if (first == last || ++next == last) return result;
156  if (comp(*next, *first))
157  result.first = *next;
158  else
159  result.second = *next;
160  first = next;
161  while (++first != last) {
162  if (++next == last) {
163  if (comp(*first, result.first))
164  result.first = *first;
165  else if (!comp(*first, result.second))
166  result.second = *first;
167  break;
168  }
169  if (comp(*next, *first)) {
170  if (comp(*next, result.first)) result.first = *next;
171  if (!comp(*first, result.second)) result.second = *first;
172  } else {
173  if (comp(*first, result.first)) result.first = *first;
174  if (!comp(*next, result.second)) result.second = *next;
175  }
176  first = next;
177  }
178  return result;
179 }
180 
181 } // namespace Kokkos
182 
183 #endif
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