1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
/*
* Copyright (C) 2018-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/vec.h"
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <limits>
namespace Math {
constexpr uint32_t nextPowerOfTwo(uint32_t value) {
--value;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
++value;
return value;
}
constexpr uint64_t nextPowerOfTwo(uint64_t value) {
--value;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value |= value >> 32;
++value;
return value;
}
constexpr uint32_t prevPowerOfTwo(uint32_t value) {
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
return (value - (value >> 1));
}
constexpr uint64_t prevPowerOfTwo(uint64_t value) {
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value |= value >> 32;
return (value - (value >> 1));
}
inline uint32_t getMinLsbSet(uint32_t value) {
static const uint8_t multiplyDeBruijnBitPosition[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
auto invert = -static_cast<int64_t>(value);
value &= static_cast<uint32_t>(invert);
return multiplyDeBruijnBitPosition[static_cast<uint32_t>(value * 0x077CB531U) >> 27];
}
constexpr uint32_t log2(uint32_t value) {
if (value == 0) {
return 32;
}
uint32_t exponent = 0u;
while (value >>= 1) {
exponent++;
}
return exponent;
}
constexpr uint32_t log2(uint64_t value) {
if (value == 0) {
return 64;
}
uint32_t exponent = 0;
while (value >>= 1) {
exponent++;
}
return exponent;
}
union FloatConversion {
uint32_t u;
float f;
};
// clang-format off
static const FloatConversion PosInfinity = {0x7f800000};
static const FloatConversion NegInfinity = {0xff800000};
static const FloatConversion Nan = {0x7fc00000};
// clang-format on
inline uint16_t float2Half(float f) {
FloatConversion u;
u.f = f;
uint32_t fsign = (u.u >> 16) & 0x8000;
float x = std::fabs(f);
//Nan
if (x != x) {
u.u >>= (24 - 11);
u.u &= 0x7fff;
u.u |= 0x0200; //silence the NaN
return u.u | fsign;
}
// overflow
if (x >= std::ldexp(1.0f, 16)) {
if (x == PosInfinity.f)
return 0x7c00 | fsign;
return 0x7bff | fsign;
}
// underflow
if (x < std::ldexp(1.0f, -24))
return fsign; // The halfway case can return 0x0001 or 0. 0 is even.
// half denormal
if (x < std::ldexp(1.0f, -14)) {
x *= std::ldexp(1.0f, 24);
return (uint16_t)((int)x | fsign);
}
u.u &= 0xFFFFE000U;
u.u -= 0x38000000U;
return (u.u >> (24 - 11)) | fsign;
}
constexpr bool isDivisibleByPowerOfTwoDivisor(uint32_t number, uint32_t divisor) {
return (number & (divisor - 1)) == 0;
}
constexpr size_t computeTotalElementsCount(const Vec3<size_t> &inputVector) {
size_t minElementCount = 1;
auto xDim = std::max(minElementCount, inputVector.x);
auto yDim = std::max(minElementCount, inputVector.y);
auto zDim = std::max(minElementCount, inputVector.z);
return xDim * yDim * zDim;
}
template <typename T>
constexpr bool isPow2(T val) {
return val != 0 && (val & (val - 1)) == 0;
}
template <typename T>
constexpr T ffs(T v) {
if (v == 0) {
return std::numeric_limits<T>::max();
}
for (T i = 0; i < sizeof(T) * 8; ++i) {
if (0 != (v & (1ULL << i))) {
return i;
}
}
std::abort();
}
constexpr size_t divideAndRoundUp(size_t dividend, size_t divisor) {
return (dividend + divisor - 1) / divisor;
}
} // namespace Math
|