alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
utility.hpp
Go to the documentation of this file.
1/* Copyright 2024 Benjamin Worpitz, René Widera, Bernhard Manfred Gruber, Jan Stephan, Andrea Bocci
2 * SPDX-License-Identifier: MPL-2.0
3 */
4#pragma once
5
7
8#include <algorithm>
9#include <bit>
10#include <climits>
11#include <concepts>
12#include <type_traits>
13#include <utility>
14
15namespace alpaka
16{
17 namespace core
18 {
19 //! convert any type to a reference type
20 //
21 // This function is equivalent to std::declval() but can be used
22 // within an alpaka accelerator kernel too.
23 // This function can be used only within std::decltype().
24#if ALPAKA_LANG_CUDA && ALPAKA_COMP_CLANG_CUDA || ALPAKA_COMP_HIP
25 template<class T>
26 ALPAKA_FN_HOST_ACC std::add_rvalue_reference_t<T> declval();
27#else
28 using std::declval;
29#endif
30 } // namespace core
31
32 /// Returns the ceiling of a / b, as integer.
33 template<std::integral Integral>
34 [[nodiscard]] ALPAKA_FN_HOST_ACC constexpr auto divCeil(Integral a, Integral b) -> Integral
35 {
36 return (a + b - Integral{1}) / b;
37 }
38
39 /// Returns the max(a / b, 1) as integer.
40 template<std::integral Integral>
41 [[nodiscard]] ALPAKA_FN_HOST_ACC constexpr auto divExZero(Integral a, Integral b) -> Integral
42 {
43 return std::max(a / b, Integral{1});
44 }
45
46 /// Computes the nth power of base, in integers.
47 template<typename Integral, typename = std::enable_if_t<std::is_integral_v<Integral>>>
48 [[nodiscard]] ALPAKA_FN_HOST_ACC constexpr auto intPow(Integral base, Integral n) -> Integral
49 {
50 if(n == 0)
51 return 1;
52 auto r = base;
53 for(Integral i = 1; i < n; i++)
54 r *= base;
55 return r;
56 }
57
58 /// Computes the floor of the nth root of value, in integers.
59 template<typename Integral, typename = std::enable_if_t<std::is_integral_v<Integral>>>
60 [[nodiscard]] ALPAKA_FN_HOST_ACC constexpr auto nthRootFloor(Integral value, Integral n) -> Integral
61 {
62 // adapted from: https://en.wikipedia.org/wiki/Integer_square_root
63 Integral L = 0;
64 Integral R = value + 1;
65 while(L != R - 1)
66 {
67 Integral const M = (L + R) / 2;
68 if(intPow(M, n) <= value)
69 L = M;
70 else
71 R = M;
72 }
73 return L;
74 }
75
76 template<std::integral T>
77 inline constexpr T firstSetBit(T value)
78 {
79 using UnsignedValueType = std::make_unsigned_t<T>;
80 return sizeof(T) * CHAR_BIT - 1 - std::countl_zero(static_cast<UnsignedValueType>(value));
81 }
82
83 /** round to the next power of two which is equal or lower to the value
84 *
85 * @param value input value >0
86 */
87 template<std::integral T>
88 inline constexpr T roundDownToPowerOfTwo(T value)
89 {
90 return T{1} << firstSetBit(value);
91 }
92
93 /** checks if T is a instance of U
94 *
95 * @tparam T full type specialization
96 * @tparam U unspecialized template type
97 *
98 * @return true if T is a specialization of U
99 *
100 * @{
101 */
102 template<typename T, template<typename...> typename U>
103 inline constexpr bool isSpecializationOf_v = std::false_type{};
104
105 template<template<typename...> typename U, typename... Vs>
106 inline constexpr bool isSpecializationOf_v<U<Vs...>, U> = std::true_type{};
107
108 /** @} */
109
110 namespace concepts
111 {
112 /** Validates if T is a specialization of the unspecialized template type U.
113 *
114 * @tparam T full type specialization
115 * @tparam U unspecialized template type
116 */
117 template<typename T, template<typename...> typename U>
119 } // namespace concepts
120
121 /**
122 * @brief Helper function calculating the integer power for the given base and exponent.
123 */
124 constexpr auto ipow(std::integral auto const base, std::integral auto const exponent)
125 requires std::same_as<ALPAKA_TYPEOF(base), ALPAKA_TYPEOF(exponent)>
126 {
127 using T_Res = ALPAKA_TYPEOF(base);
128 T_Res result = T_Res{1};
129 if(exponent == T_Res{0})
130 return result;
131
132 result = ipow(base, exponent / T_Res{2});
133 result *= result;
134
135 if(exponent % T_Res{2})
136 result *= base;
137
138 return result;
139 }
140} // namespace alpaka
#define ALPAKA_FN_HOST_ACC
All functions that can be used on an accelerator have to be attributed with ALPAKA_FN_ACC or ALPAKA_F...
Definition common.hpp:32
#define ALPAKA_TYPEOF(...)
Get the type of instance.
Definition common.hpp:154
Validates if T is a specialization of the unspecialized template type U.
Definition utility.hpp:118
main alpaka namespace.
Definition alpaka.hpp:76
ALPAKA_FN_HOST_ACC constexpr auto divExZero(Integral a, Integral b) -> Integral
Returns the max(a / b, 1) as integer.
Definition utility.hpp:41
constexpr T firstSetBit(T value)
Definition utility.hpp:77
ALPAKA_FN_HOST_ACC constexpr auto divCeil(Integral a, Integral b) -> Integral
Returns the ceiling of a / b, as integer.
Definition utility.hpp:34
ALPAKA_FN_HOST_ACC constexpr auto intPow(Integral base, Integral n) -> Integral
Computes the nth power of base, in integers.
Definition utility.hpp:48
constexpr T roundDownToPowerOfTwo(T value)
round to the next power of two which is equal or lower to the value
Definition utility.hpp:88
ALPAKA_FN_HOST_ACC constexpr auto nthRootFloor(Integral value, Integral n) -> Integral
Computes the floor of the nth root of value, in integers.
Definition utility.hpp:60
constexpr auto ipow(std::integral auto const base, std::integral auto const exponent)
Helper function calculating the integer power for the given base and exponent.
Definition utility.hpp:124
constexpr bool isSpecializationOf_v
checks if T is a instance of U
Definition utility.hpp:103