Skip to content

Commit b4c322a

Browse files
[SYCL] Allow fpga_reg only for PODs and Trivially-copyable structs (#3643)
This change restricts the INTEL::fpga_reg function to only take in trivially copyable structs, and models the hardware better but created a registered copy, rather than just passing through as a reference. The intention of this function was initially built for PODs and later extended to structs in OpenCL. It literally is used to force a register stage in hardware between the input and output (i.e. in the software model, it is an exact copy of the data in memory). It doesn't translate directly to C++ objects because classes with complex copy constructors cannot be modelled to do what is described above, and building out this builtin in hardware as per the software model reduces its use case. As such, restricting the function to only types that have a usable and correct implementation of this function is the ideal thing to do here Note that I also removed the old mapping to intelfpga::fpga_reg as part of this changelist. Testing: - Ran this new header file with a variety of SYCL examples in the FPGA design suite to ensure that it was still behaving in its intended behavior
1 parent 33bc8ad commit b4c322a

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

sycl/include/CL/sycl/INTEL/fpga_reg.hpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,31 @@
99
#pragma once
1010

1111
#include <CL/sycl/detail/defines.hpp>
12+
#include <type_traits>
1213

1314
__SYCL_INLINE_NAMESPACE(cl) {
1415
namespace sycl {
1516
namespace INTEL {
1617

17-
template <typename _T> _T fpga_reg(const _T &t) {
18+
// Returns a registered copy of the input
19+
// This function is intended for FPGA users to instruct the compiler to insert
20+
// at least one register stage between the input and the return value.
21+
template <typename _T>
22+
typename std::enable_if<std::is_trivially_copyable<_T>::value, _T>::type
23+
fpga_reg(_T t) {
24+
#if __has_builtin(__builtin_intel_fpga_reg)
25+
return __builtin_intel_fpga_reg(t);
26+
#else
27+
return t;
28+
#endif
29+
}
30+
31+
template <typename _T>
32+
[[deprecated("INTEL::fpga_reg will only support trivially_copyable types in a "
33+
"future release. The type used here will be disallowed.")]]
34+
typename std::enable_if<std::is_trivially_copyable<_T>::value == false,
35+
_T>::type
36+
fpga_reg(_T t) {
1837
#if __has_builtin(__builtin_intel_fpga_reg)
1938
return __builtin_intel_fpga_reg(t);
2039
#else
@@ -29,7 +48,9 @@ template <typename _T> _T fpga_reg(const _T &t) {
2948
// Keep it consistent with FPGA attributes like intelfpga::memory()
3049
// Currently clang does not support nested namespace for attributes
3150
namespace intelfpga {
32-
template <typename _T> _T fpga_reg(const _T &t) {
51+
template <typename _T>
52+
[[deprecated("intelfpga::fpga_reg will be removed in a future release.")]] _T
53+
fpga_reg(const _T &t) {
3354
return cl::sycl::INTEL::fpga_reg(t);
3455
}
3556
} // namespace intelfpga

0 commit comments

Comments
 (0)