Skip to content

Commit 8636e75

Browse files
[SYCL][FPGA] Update handler of variadic template argument list to support more types other than int32_t (#3957)
This patch is a prerequisite for the upcoming FPGA latency control feature.
1 parent e612834 commit 8636e75

File tree

3 files changed

+73
-25
lines changed

3 files changed

+73
-25
lines changed

sycl/include/CL/sycl/INTEL/fpga_lsu.hpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,27 @@ constexpr uint8_t CACHE = 0x2;
1919
constexpr uint8_t STATICALLY_COALESCE = 0x4;
2020
constexpr uint8_t PREFETCH = 0x8;
2121

22-
template <int32_t _N> struct burst_coalesce_impl {
23-
static constexpr int32_t value = _N;
24-
static constexpr int32_t default_value = 0;
22+
struct burst_coalesce_impl_id;
23+
template <int32_t _N>
24+
struct burst_coalesce_impl : std::integral_constant<int32_t, _N> {
25+
using type_id = burst_coalesce_impl_id;
2526
};
2627

27-
template <int32_t _N> struct cache {
28-
static constexpr int32_t value = _N;
29-
static constexpr int32_t default_value = 0;
28+
struct cache_id;
29+
template <int32_t _N> struct cache : std::integral_constant<int32_t, _N> {
30+
using type_id = cache_id;
3031
};
3132

32-
template <int32_t _N> struct prefetch_impl {
33-
static constexpr int32_t value = _N;
34-
static constexpr int32_t default_value = 0;
33+
struct prefetch_impl_id;
34+
template <int32_t _N>
35+
struct prefetch_impl : std::integral_constant<int32_t, _N> {
36+
using type_id = prefetch_impl_id;
3537
};
3638

37-
template <int32_t _N> struct statically_coalesce_impl {
38-
static constexpr int32_t value = _N;
39-
static constexpr int32_t default_value = 1;
39+
struct statically_coalesce_impl_id;
40+
template <int32_t _N>
41+
struct statically_coalesce_impl : std::integral_constant<int32_t, _N> {
42+
using type_id = statically_coalesce_impl_id;
4043
};
4144

4245
template <bool _B> using burst_coalesce = burst_coalesce_impl<_B>;
@@ -77,21 +80,21 @@ template <class... _mem_access_params> class lsu final {
7780

7881
private:
7982
static constexpr int32_t _burst_coalesce_val =
80-
_GetValue<burst_coalesce_impl, _mem_access_params...>::value;
83+
_GetValue<burst_coalesce_impl<0>, _mem_access_params...>::value;
8184
static constexpr uint8_t _burst_coalesce =
8285
_burst_coalesce_val == 1 ? BURST_COALESCE : 0;
8386

8487
static constexpr int32_t _cache_val =
85-
_GetValue<cache, _mem_access_params...>::value;
88+
_GetValue<cache<0>, _mem_access_params...>::value;
8689
static constexpr uint8_t _cache = (_cache_val > 0) ? CACHE : 0;
8790

8891
static constexpr int32_t _statically_coalesce_val =
89-
_GetValue<statically_coalesce_impl, _mem_access_params...>::value;
92+
_GetValue<statically_coalesce_impl<1>, _mem_access_params...>::value;
9093
static constexpr uint8_t _dont_statically_coalesce =
9194
_statically_coalesce_val == 0 ? STATICALLY_COALESCE : 0;
9295

9396
static constexpr int32_t _prefetch_val =
94-
_GetValue<prefetch_impl, _mem_access_params...>::value;
97+
_GetValue<prefetch_impl<0>, _mem_access_params...>::value;
9598
static constexpr uint8_t _prefetch = _prefetch_val ? PREFETCH : 0;
9699

97100
static_assert(_cache_val >= 0, "cache size parameter must be non-negative");

sycl/include/CL/sycl/INTEL/fpga_utils.hpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,25 @@ __SYCL_INLINE_NAMESPACE(cl) {
1616
namespace sycl {
1717
namespace INTEL {
1818

19-
template <template <int32_t> class _Type, class _T>
20-
struct _MatchType : std::is_same<_Type<_T::value>, _T> {};
19+
template <class _D, class _T>
20+
struct _MatchType : std::is_same<typename _D::type_id, typename _T::type_id> {};
2121

22-
template <template <int32_t> class _Type, class... _T> struct _GetValue {
23-
static constexpr auto value = _Type<0>::default_value;
22+
template <class _D, class... _T> struct _GetValue;
23+
24+
template <class _D>
25+
struct _GetValue<_D> : std::integral_constant<decltype(_D::value), _D::value> {
2426
};
2527

26-
template <template <int32_t> class _Type, class _T1, class... _T>
27-
struct _GetValue<_Type, _T1, _T...> {
28-
static constexpr auto value =
29-
detail::conditional_t<_MatchType<_Type, _T1>::value, _T1,
30-
_GetValue<_Type, _T...>>::value;
28+
template <class _D, class _T1, class... _T> struct _GetValue<_D, _T1, _T...> {
29+
template <class _D2, class _T12, class _Enable = void>
30+
struct impl : std::integral_constant<decltype(_D::value),
31+
_GetValue<_D, _T...>::value> {};
32+
33+
template <class _D2, class _T12>
34+
struct impl<_D2, _T12, std::enable_if_t<_MatchType<_D2, _T12>::value>>
35+
: std::integral_constant<decltype(_D::value), _T1::value> {};
36+
37+
static constexpr auto value = impl<_D, _T1>::value;
3138
};
3239
} // namespace INTEL
3340
} // namespace sycl
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %clangxx -fsycl -fsyntax-only -Xclang -verify %s -Xclang -verify-ignore-unexpected=note,warning
2+
// expected-no-diagnostics
3+
4+
// This test performs basic check of SYCL FPGA arbitrary template argument list.
5+
6+
#include <CL/sycl.hpp>
7+
#include <CL/sycl/INTEL/fpga_utils.hpp>
8+
#include <iostream>
9+
10+
enum class enumClass { first, second };
11+
12+
struct testIntID;
13+
template <int _N> struct testInt : std::integral_constant<int, _N> {
14+
using type_id = testIntID;
15+
};
16+
17+
struct testEnumID;
18+
template <enumClass _N>
19+
struct testEnum : std::integral_constant<enumClass, _N> {
20+
using type_id = testEnumID;
21+
};
22+
23+
template <int ExpectedIntValue, enumClass ExpectedEnumValue, class... _Params>
24+
void func() {
25+
static_assert(sycl::INTEL::_GetValue<testInt<0>, _Params...>::value ==
26+
ExpectedIntValue);
27+
static_assert(
28+
sycl::INTEL::_GetValue<testEnum<enumClass::first>, _Params...>::value ==
29+
ExpectedEnumValue);
30+
}
31+
32+
int main() {
33+
func<0, enumClass::first>();
34+
func<1, enumClass::first, testInt<1>>();
35+
func<0, enumClass::second, testEnum<enumClass::second>>();
36+
func<1, enumClass::second, testInt<1>, testEnum<enumClass::second>>();
37+
func<1, enumClass::second, testEnum<enumClass::second>, testInt<1>>();
38+
}

0 commit comments

Comments
 (0)