mirror of
https://github.com/intel/compute-runtime.git
synced 2025-11-10 05:49:51 +08:00
Adding ffs and 64-bit prev/next pow2
Change-Id: Ie10731c16b65a4fd1f36fd4c9bbca9a6951583a1
This commit is contained in:
committed by
sys_ocldev
parent
b11e0825c9
commit
22448ee265
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -1,5 +1,5 @@
|
|||||||
#!groovy
|
#!groovy
|
||||||
dependenciesRevision='36a2a0d6a9da5e506439ffcb8dcf49d3e8f0e175-1185'
|
dependenciesRevision='36a2a0d6a9da5e506439ffcb8dcf49d3e8f0e175-1185'
|
||||||
strategy='EQUAL'
|
strategy='EQUAL'
|
||||||
allowedCD=272
|
allowedCD=270
|
||||||
allowedF=4
|
allowedF=4
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2017-2018 Intel Corporation
|
* Copyright (C) 2017-2019 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
namespace OCLRT {
|
namespace OCLRT {
|
||||||
namespace Math {
|
namespace Math {
|
||||||
|
|
||||||
inline uint32_t nextPowerOfTwo(uint32_t value) {
|
constexpr uint32_t nextPowerOfTwo(uint32_t value) {
|
||||||
--value;
|
--value;
|
||||||
value |= value >> 1;
|
value |= value >> 1;
|
||||||
value |= value >> 2;
|
value |= value >> 2;
|
||||||
@@ -31,12 +31,34 @@ inline uint32_t nextPowerOfTwo(uint32_t value) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t prevPowerOfTwo(uint32_t value) {
|
constexpr uint64_t nextPowerOfTwo(uint64_t value) {
|
||||||
|
--value;
|
||||||
value |= value >> 1;
|
value |= value >> 1;
|
||||||
value |= value >> 2;
|
value |= value >> 2;
|
||||||
value |= value >> 4;
|
value |= value >> 4;
|
||||||
value |= value >> 8;
|
value |= value >> 8;
|
||||||
value |= value >> 16;
|
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));
|
return (value - (value >> 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +71,7 @@ inline uint32_t getMinLsbSet(uint32_t value) {
|
|||||||
return multiplyDeBruijnBitPosition[static_cast<uint32_t>(value * 0x077CB531U) >> 27];
|
return multiplyDeBruijnBitPosition[static_cast<uint32_t>(value * 0x077CB531U) >> 27];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint32_t log2(uint32_t value) {
|
constexpr uint32_t log2(uint32_t value) {
|
||||||
uint32_t exponent = 0u;
|
uint32_t exponent = 0u;
|
||||||
uint32_t startVal = value;
|
uint32_t startVal = value;
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
@@ -65,7 +87,7 @@ inline uint32_t log2(uint32_t value) {
|
|||||||
return exponent;
|
return exponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t log2(uint64_t value) {
|
constexpr uint64_t log2(uint64_t value) {
|
||||||
uint64_t exponent = 0;
|
uint64_t exponent = 0;
|
||||||
uint64_t startVal = value;
|
uint64_t startVal = value;
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
@@ -141,7 +163,7 @@ inline bool isDivisableByPowerOfTwoDivisor(uint32_t number, uint32_t divisor) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t computeTotalElementsCount(const Vec3<size_t> &inputVector) {
|
constexpr size_t computeTotalElementsCount(const Vec3<size_t> &inputVector) {
|
||||||
size_t minElementCount = 1;
|
size_t minElementCount = 1;
|
||||||
auto xDim = std::max(minElementCount, inputVector.x);
|
auto xDim = std::max(minElementCount, inputVector.x);
|
||||||
auto yDim = std::max(minElementCount, inputVector.y);
|
auto yDim = std::max(minElementCount, inputVector.y);
|
||||||
@@ -150,7 +172,7 @@ inline size_t computeTotalElementsCount(const Vec3<size_t> &inputVector) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool isPow2(T val) {
|
constexpr bool isPow2(T val) {
|
||||||
if (val != 0) {
|
if (val != 0) {
|
||||||
if ((val & (val - 1)) == 0) {
|
if ((val & (val - 1)) == 0) {
|
||||||
return true;
|
return true;
|
||||||
@@ -159,5 +181,20 @@ bool isPow2(T val) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UNREACHABLE("Either v==0 or any of bits is set");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Math
|
} // namespace Math
|
||||||
} // namespace OCLRT
|
} // namespace OCLRT
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2017-2018 Intel Corporation
|
* Copyright (C) 2017-2019 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
OCLRT::abortUnrecoverable(__LINE__, __FILE__); \
|
OCLRT::abortUnrecoverable(__LINE__, __FILE__); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define UNREACHABLE(...) std::abort()
|
||||||
|
|
||||||
#ifndef DEBUG_BREAK_IF
|
#ifndef DEBUG_BREAK_IF
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define DEBUG_BREAK_IF(expression) \
|
#define DEBUG_BREAK_IF(expression) \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2017-2018 Intel Corporation
|
* Copyright (C) 2017-2019 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
@@ -12,19 +12,22 @@ using namespace OCLRT::Math;
|
|||||||
using namespace OCLRT;
|
using namespace OCLRT;
|
||||||
|
|
||||||
TEST(NextPowerOfTwo, aFewCases) {
|
TEST(NextPowerOfTwo, aFewCases) {
|
||||||
EXPECT_EQ(1u, nextPowerOfTwo(1));
|
EXPECT_EQ(1u, nextPowerOfTwo(1U));
|
||||||
EXPECT_EQ(2u, nextPowerOfTwo(2));
|
EXPECT_EQ(2u, nextPowerOfTwo(2U));
|
||||||
EXPECT_EQ(4u, nextPowerOfTwo(3));
|
EXPECT_EQ(4u, nextPowerOfTwo(3U));
|
||||||
EXPECT_EQ(32u, nextPowerOfTwo(31));
|
EXPECT_EQ(32u, nextPowerOfTwo(31U));
|
||||||
EXPECT_EQ(32u, nextPowerOfTwo(32));
|
EXPECT_EQ(32u, nextPowerOfTwo(32U));
|
||||||
EXPECT_EQ(64u, nextPowerOfTwo(33));
|
EXPECT_EQ(64u, nextPowerOfTwo(33U));
|
||||||
EXPECT_EQ(1u << 31, nextPowerOfTwo((1u << 30) + 1));
|
EXPECT_EQ(1u << 31, nextPowerOfTwo((1u << 30U) + 1));
|
||||||
EXPECT_EQ(1u << 31, nextPowerOfTwo(1u << 31));
|
EXPECT_EQ(1u << 31, nextPowerOfTwo(1u << 31U));
|
||||||
|
|
||||||
|
EXPECT_EQ(1ULL << 32, nextPowerOfTwo(static_cast<uint64_t>((1ULL << 31ULL) + 1)));
|
||||||
|
EXPECT_EQ(1ULL << 32, nextPowerOfTwo(static_cast<uint64_t>(1ULL << 32ULL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PrevPowerOfTwo, aroundPowers) {
|
TEST(PrevPowerOfTwo, aroundPowers) {
|
||||||
EXPECT_EQ(0u, prevPowerOfTwo(0));
|
EXPECT_EQ(0u, prevPowerOfTwo(0U));
|
||||||
EXPECT_EQ(1u, prevPowerOfTwo(1));
|
EXPECT_EQ(1u, prevPowerOfTwo(1U));
|
||||||
for (uint32_t i = 1; i < 32; i++) {
|
for (uint32_t i = 1; i < 32; i++) {
|
||||||
uint32_t b = 1 << i;
|
uint32_t b = 1 << i;
|
||||||
|
|
||||||
@@ -32,6 +35,9 @@ TEST(PrevPowerOfTwo, aroundPowers) {
|
|||||||
EXPECT_EQ(b, prevPowerOfTwo(b));
|
EXPECT_EQ(b, prevPowerOfTwo(b));
|
||||||
EXPECT_EQ(b, prevPowerOfTwo(b + 1));
|
EXPECT_EQ(b, prevPowerOfTwo(b + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(1ULL << 32, prevPowerOfTwo(static_cast<uint64_t>(1ULL << 32ULL)));
|
||||||
|
EXPECT_EQ(1ULL << 32, prevPowerOfTwo(static_cast<uint64_t>((1ULL << 32ULL) + 7)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(getMinLsbSet, basicValues) {
|
TEST(getMinLsbSet, basicValues) {
|
||||||
@@ -193,3 +199,18 @@ TEST(isPow2Test, WhenArgPow2ThenReturnTrue) {
|
|||||||
EXPECT_TRUE(isPow2(128u));
|
EXPECT_TRUE(isPow2(128u));
|
||||||
EXPECT_TRUE(isPow2(4096u));
|
EXPECT_TRUE(isPow2(4096u));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ffs, givenZeroReturnMaxRange) {
|
||||||
|
EXPECT_EQ(std::numeric_limits<uint32_t>::max(), ffs(0U));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ffs, givenNonZeroReturnFirstSetBitIndex) {
|
||||||
|
EXPECT_EQ(0U, ffs(0b1U));
|
||||||
|
EXPECT_EQ(0U, ffs(0b11U));
|
||||||
|
EXPECT_EQ(1U, ffs(0b10U));
|
||||||
|
EXPECT_EQ(3U, ffs(0b1001000U));
|
||||||
|
EXPECT_EQ(31U, ffs(1U << 31U));
|
||||||
|
EXPECT_EQ(16U, ffs((1U << 31U) | (1U << 31U) | (1U << 16U)));
|
||||||
|
EXPECT_EQ(16ULL, ffs((1ULL << 63ULL) | (1ULL << 32ULL) | (1ULL << 16ULL)));
|
||||||
|
EXPECT_EQ(63ULL, ffs(1ULL << 63ULL));
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user