Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate simdForEach #2: remove unroll step #2275

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions folly/algorithm/simd/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ cpp_library(
headers = ["SimdForEach.h"],
exported_deps = [
"//folly:c_portability",
"//folly:traits",
"//folly/algorithm/simd/detail:unroll_utils",
],
)
25 changes: 11 additions & 14 deletions folly/algorithm/simd/SimdForEach.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#pragma once

#include <folly/CPortability.h>
#include <folly/Traits.h>
#include <folly/algorithm/simd/detail/UnrollUtils.h>

#include <array>
Expand Down Expand Up @@ -110,10 +111,9 @@ FOLLY_ALWAYS_INLINE T* previousAlignedAddress(T* ptr, int to) {
struct SimdForEachMainLoop {
template <typename T, typename Delegate>
FOLLY_ALWAYS_INLINE bool operator()(
int cardinal, T*& f, T* l, Delegate& delegate, detail::UnrollStep<1>)
const {
int cardinal, T*& f, T* l, Delegate& delegate, index_constant<1>) const {
while (f != l) {
if (delegate.step(f, ignore_none{}, detail::UnrollStep<0>{}))
if (delegate.step(f, ignore_none{}, index_constant<0>{}))
return true;
f += cardinal;
}
Expand All @@ -129,8 +129,8 @@ struct SimdForEachMainLoop {
T* l;
Delegate& delegate;

template <int i>
FOLLY_ALWAYS_INLINE bool operator()(detail::UnrollStep<i> unrollI) {
template <std::size_t i>
FOLLY_ALWAYS_INLINE bool operator()(index_constant<i> unrollI) {
if (f == l)
return true;

Expand All @@ -140,13 +140,10 @@ struct SimdForEachMainLoop {
}
};

template <typename T, typename Delegate, int unrolling>
template <typename T, typename Delegate, std::size_t unrolling>
FOLLY_ALWAYS_INLINE bool operator()(
int cardinal,
T*& f,
T* l,
Delegate& delegate,
detail::UnrollStep<unrolling>) const {
int cardinal, T*& f, T* l, Delegate& delegate, index_constant<unrolling>)
const {
// Not enough to fully unroll explanation.
//
// There are a few approaches to handle this:
Expand Down Expand Up @@ -206,14 +203,14 @@ FOLLY_ALWAYS_INLINE void simdForEachAligning(
ignore_extrema ignore{static_cast<int>(f - af), 0};
if (af != al) {
// first chunk
if (delegate.step(af, ignore, detail::UnrollStep<0>{})) {
if (delegate.step(af, ignore, index_constant<0>{})) {
return;
}
ignore.first = 0;
af += cardinal;

if (SimdForEachMainLoop{}(
cardinal, af, al, delegate, detail::UnrollStep<unrolling>{})) {
cardinal, af, al, delegate, index_constant<unrolling>{})) {
return;
}

Expand All @@ -224,7 +221,7 @@ FOLLY_ALWAYS_INLINE void simdForEachAligning(
}

ignore.last = static_cast<int>(af + cardinal - l);
delegate.step(af, ignore, detail::UnrollStep<0>{});
delegate.step(af, ignore, index_constant<0>{});
}

} // namespace simd_detail
Expand Down
1 change: 1 addition & 0 deletions folly/algorithm/simd/detail/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ cpp_library(
headers = ["UnrollUtils.h"],
exported_deps = [
"//folly:portability",
"//folly:traits",
],
)
32 changes: 12 additions & 20 deletions folly/algorithm/simd/detail/UnrollUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@
#pragma once

#include <folly/Portability.h>
#include <folly/Traits.h>

#include <array>
#include <type_traits>

namespace folly {
namespace detail {

template <int i>
struct UnrollStep : std::integral_constant<int, i> {};
namespace folly::detail {

/**
* UnrollUtils
Expand Down Expand Up @@ -67,13 +65,14 @@ struct UnrollUtils {
* unrollUntil<N>(op)
*
* Do operation N times or until it returns true to break.
* Op accepts UnrollStep<i> so it can keep track of a step begin executed.
* Op accepts integral_constant<i> so it can keep track of a step begin
* executed.
*
* Returns wether true if it was interrupted (you can know if the op breaked)
*/
template <int N, typename Op>
template <std::size_t N, typename Op>
FOLLY_ALWAYS_INLINE static constexpr bool unrollUntil(Op op) {
return unrollUntilImpl<N, 0>(op);
return unrollUntilImpl(op, std::make_index_sequence<N>{});
}

private:
Expand Down Expand Up @@ -117,18 +116,11 @@ struct UnrollUtils {
return op(leftSum, rightSum);
}

template <int N, int i, typename Op>
FOLLY_ALWAYS_INLINE static constexpr std::enable_if_t<i == N, bool>
unrollUntilImpl(Op) {
return false;
}

template <int N, int i, typename Op>
FOLLY_ALWAYS_INLINE static constexpr std::enable_if_t<i != N, bool>
unrollUntilImpl(Op op) {
return op(UnrollStep<i>{}) || unrollUntilImpl<N, i + 1>(op);
template <typename Op, std::size_t... i>
FOLLY_ALWAYS_INLINE static constexpr bool unrollUntilImpl(
Op op, std::index_sequence<i...>) {
return (... || op(index_constant<i>{}));
}
};

} // namespace detail
} // namespace folly
} // namespace folly::detail
22 changes: 14 additions & 8 deletions folly/algorithm/simd/detail/test/UnrollUtilsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,26 @@ TEST(UnrollUtilsTest, ArrayReduce) {
static_assert(10 == reduceValues<1, 2, 3, 4>(), "");
}

template <int stopAt>
template <std::size_t stopAt>
struct UnrollUntilTestOp {
int* lastStep;
std::size_t* lastStep;

template <int i>
constexpr bool operator()(UnrollStep<i>) const {
template <std::size_t i>
constexpr bool operator()(folly::index_constant<i>) const {
*lastStep = i;
return i == stopAt;
}
};

template <int N, int stopAt, bool expectedRes, int expectedLastStep>
constexpr std::size_t kNoStop = std::numeric_limits<std::size_t>::max();

template <
std::size_t N,
std::size_t stopAt,
bool expectedRes,
std::size_t expectedLastStep>
constexpr bool unrollUntilTest() {
int lastStep = -1;
std::size_t lastStep = kNoStop;
UnrollUntilTestOp<stopAt> op{&lastStep};
bool res = UnrollUtils::unrollUntil<N>(op);

Expand All @@ -77,14 +83,14 @@ TEST(UnrollUtilsTest, UnrollUntil) {
/*N*/ 0,
/*stopAt*/ 0,
/*expectedRes*/ false,
/*ExpectedLastStep*/ -1>(),
/*ExpectedLastStep*/ kNoStop>(),
"");
static_assert(
unrollUntilTest<
/*N*/ 0,
/*stopAt*/ 1,
/*expectedRes*/ false,
/*ExpectedLastStep*/ -1>(),
/*ExpectedLastStep*/ kNoStop>(),
"");
static_assert(
unrollUntilTest<
Expand Down
2 changes: 1 addition & 1 deletion folly/algorithm/simd/test/SimdForEachTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ struct TestDelegate {
return step(
unrolled[unrollI()],
ignore_none{},
detail::UnrollStep<decltype(unrollI)::value + ('A' - 'a')>{});
folly::index_constant<decltype(unrollI)::value + ('A' - 'a')>{});
});
}
};
Expand Down
Loading