Skip to content

Commit 7b9001e

Browse files
[SYCL][FPGA] Implement task_sequence header, properties, and add new fpga_cluster kernel property (intel#12453)
Implement task_sequence header, task_sequence properties, and fpga_cluster kernel property according to the spec updates intel#6348 (almost ready to be merged) Header - Refactor invocation and response capacity to be on the Create intrinsic, so Async and Get do not take in respective argument - Remove max_outstanding argument of Create intrinsic - Add pipelined and fpga_cluster arguments to Create intrinsic - Async, Get, and Release intrinsic now accept the TargetExtType target("spirv.TaskSequenceINTEL") returned from the Create intrinsic, and do not take in object pointer or task function pointer arguments - Task Sequence accepts properties Task Sequence Properties - Convert invocation and response capacity from template parameters to properties - Add balanced property to remove Get intrinsic loop in destructor FPGA Kernel properties - Add fpga_cluster property - Support fpga_cluster and pipelined property for task sequence
1 parent 2525570 commit 7b9001e

32 files changed

+1206
-33
lines changed

clang/lib/CodeGen/CodeGenTypes.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,11 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
654654
"__spv::__spirv_JointMatrixINTEL") {
655655
ResultType = ConvertSYCLJointMatrixINTELType(RD);
656656
break;
657+
} else if (RD && RD->getQualifiedNameAsString() ==
658+
"__spv::__spirv_TaskSequenceINTEL") {
659+
ResultType = llvm::TargetExtType::get(getLLVMContext(),
660+
"spirv.TaskSequenceINTEL");
661+
break;
657662
}
658663
}
659664
}

clang/lib/Driver/ToolChains/Clang.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -10235,7 +10235,8 @@ void SPIRVTranslator::ConstructJob(Compilation &C, const JobAction &JA,
1023510235
",+SPV_INTEL_fpga_buffer_location"
1023610236
",+SPV_INTEL_fpga_argument_interfaces"
1023710237
",+SPV_INTEL_fpga_invocation_pipelining_attributes"
10238-
",+SPV_INTEL_fpga_latency_control";
10238+
",+SPV_INTEL_fpga_latency_control"
10239+
",+SPV_INTEL_task_sequence";
1023910240
ExtArg = ExtArg + DefaultExtArg + INTELExtArg;
1024010241
if (C.getDriver().IsFPGAHWMode())
1024110242
// Enable several extensions on FPGA H/W exclusively
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -triple spir64-unknown-unknown -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s
2+
3+
// Test that SPIR-V codegen generates the expected LLVM struct name for the
4+
// TaskSequenceINTEL type
5+
6+
namespace __spv {
7+
struct __spirv_TaskSequenceINTEL;
8+
} // namespace __spv
9+
10+
// CHECK: @_Z4func{{.*}}(target("spirv.TaskSequenceINTEL")
11+
void func(__spv::__spirv_TaskSequenceINTEL *task_seq) {}

clang/test/Driver/sycl-spirv-ext.c

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
// CHECK-DEFAULT-SAME:,+SPV_INTEL_fpga_argument_interfaces
4848
// CHECK-DEFAULT-SAME:,+SPV_INTEL_fpga_invocation_pipelining_attributes
4949
// CHECK-DEFAULT-SAME:,+SPV_INTEL_fpga_latency_control
50+
// CHECK-DEFAULT-SAME:,+SPV_INTEL_task_sequence
5051
// CHECK-DEFAULT-SAME:,+SPV_INTEL_token_type
5152
// CHECK-DEFAULT-SAME:,+SPV_INTEL_bfloat16_conversion
5253
// CHECK-DEFAULT-SAME:,+SPV_INTEL_joint_matrix
@@ -77,6 +78,7 @@
7778
// CHECK-FPGA-HW-SAME:,+SPV_INTEL_fpga_buffer_location
7879
// CHECK-FPGA-HW-SAME:,+SPV_INTEL_fpga_argument_interfaces
7980
// CHECK-FPGA-HW-SAME:,+SPV_INTEL_fpga_latency_control
81+
// CHECK-FPGA-HW-SAME:,+SPV_INTEL_task_sequence
8082
// CHECK-FPGA-HW-SAME:,+SPV_INTEL_usm_storage_classes
8183
// CHECK-FPGA-HW-SAME:,+SPV_INTEL_runtime_aligned
8284
// CHECK-FPGA-HW-SAME:,+SPV_INTEL_fpga_cluster_attributes,+SPV_INTEL_loop_fuse
@@ -108,6 +110,7 @@
108110
// CHECK-CPU-SAME:,+SPV_INTEL_fpga_argument_interfaces
109111
// CHECK-CPU-SAME:,+SPV_INTEL_fpga_invocation_pipelining_attributes
110112
// CHECK-CPU-SAME:,+SPV_INTEL_fpga_latency_control
113+
// CHECK-CPU-SAME:,+SPV_INTEL_task_sequence
111114
// CHECK-CPU-SAME:,+SPV_INTEL_token_type
112115
// CHECK-CPU-SAME:,+SPV_INTEL_bfloat16_conversion
113116
// CHECK-CPU-SAME:,+SPV_INTEL_joint_matrix

llvm/include/llvm/SYCLLowerIR/DeviceConfigFile.td

+3-1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def AspectExt_intel_matrix : Aspect<"ext_intel_matrix">;
7070
def AspectExt_oneapi_is_composite : Aspect<"ext_oneapi_is_composite">;
7171
def AspectExt_oneapi_is_component : Aspect<"ext_oneapi_is_component">;
7272
def AspectExt_oneapi_graph : Aspect<"ext_oneapi_graph">;
73+
def AspectExt_intel_fpga_task_sequence : Aspect<"ext_intel_fpga_task_sequence">;
7374
// Deprecated aspects
7475
def AspectInt64_base_atomics : Aspect<"int64_base_atomics">;
7576
def AspectInt64_extended_atomics : Aspect<"int64_extended_atomics">;
@@ -120,7 +121,8 @@ def : TargetInfo<"__TestAspectList",
120121
AspectExt_oneapi_interop_semaphore_import, AspectExt_oneapi_interop_semaphore_export,
121122
AspectExt_oneapi_mipmap, AspectExt_oneapi_mipmap_anisotropy, AspectExt_oneapi_mipmap_level_reference, AspectExt_intel_esimd,
122123
AspectExt_oneapi_ballot_group, AspectExt_oneapi_fixed_size_group, AspectExt_oneapi_opportunistic_group,
123-
AspectExt_oneapi_tangle_group, AspectExt_intel_matrix, AspectExt_oneapi_is_composite, AspectExt_oneapi_is_component, AspectExt_oneapi_graph],
124+
AspectExt_oneapi_tangle_group, AspectExt_intel_matrix, AspectExt_oneapi_is_composite, AspectExt_oneapi_is_component,
125+
AspectExt_oneapi_graph, AspectExt_intel_fpga_task_sequence],
124126
[]>;
125127
// This definition serves the only purpose of testing whether the deprecated aspect list defined in here and in SYCL RT
126128
// match.

llvm/lib/SYCLLowerIR/CompileTimePropertiesPass.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ attributeToExecModeMetadata(const Attribute &Attr, Function &F) {
416416

417417
if (AttrKindStr == "sycl-streaming-interface") {
418418
// generate either:
419+
// !ip_interface !N
419420
// !N = !{!"streaming"} or
420421
// !N = !{!"streaming", !"stall_free_return"}
421422
SmallVector<Metadata *, 2> MD;
@@ -428,6 +429,7 @@ attributeToExecModeMetadata(const Attribute &Attr, Function &F) {
428429

429430
if (AttrKindStr == "sycl-register-map-interface") {
430431
// generate either:
432+
// !ip_interface !N
431433
// !N = !{!"csr"} or
432434
// !N = !{!"csr", !"wait_for_done_write"}
433435
SmallVector<Metadata *, 2> MD;
@@ -438,6 +440,20 @@ attributeToExecModeMetadata(const Attribute &Attr, Function &F) {
438440
MDNode::get(Ctx, MD));
439441
}
440442

443+
if (AttrKindStr == "sycl-fpga-cluster") {
444+
// generate either:
445+
// !stall_free !N
446+
// !N = !{i32 1} or
447+
// !stall_enable !N
448+
// !N = !{i32 1}
449+
std::string ClusterType =
450+
getAttributeAsInteger<uint32_t>(Attr) ? "stall_enable" : "stall_free";
451+
Metadata *ClusterMDArgs[] = {
452+
ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Ctx), 1))};
453+
return std::pair<std::string, MDNode *>(ClusterType,
454+
MDNode::get(Ctx, ClusterMDArgs));
455+
}
456+
441457
if ((AttrKindStr == SYCL_REGISTER_ALLOC_MODE_ATTR ||
442458
AttrKindStr == SYCL_GRF_SIZE_ATTR) &&
443459
!llvm::esimd::isESIMD(F)) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; Check conversion of sycl-fpga-cluster attribute
2+
; RUN: opt -passes="compile-time-properties" %s -S -o - | FileCheck %s --check-prefix CHECK-IR
3+
4+
; CHECK-IR-DAG: @stallFree() #0 {{.*}}!stall_free [[MD_TRUE:![0-9]+]] {
5+
; Function Attrs: convergent norecurse
6+
define weak_odr dso_local spir_kernel void @stallFree() #0 {
7+
entry:
8+
ret void
9+
}
10+
11+
; CHECK-IR-DAG: @stallEnable() #1 {{.*}}!stall_enable [[MD_TRUE:![0-9]+]] {
12+
; Function Attrs: convergent norecurse
13+
define weak_odr dso_local spir_kernel void @stallEnable() #1 {
14+
entry:
15+
ret void
16+
}
17+
18+
attributes #0 = { convergent norecurse "frame-pointer"="all" "sycl-fpga-cluster"="0" }
19+
attributes #1 = { convergent norecurse "frame-pointer"="all" "sycl-fpga-cluster"="1" }
20+
21+
!opencl.spir.version = !{!0, !0, !0, !0, !0, !0, !0, !0, !0, !0, !0}
22+
!spirv.Source = !{!1, !1, !1, !1, !1, !1, !1, !1, !1, !1, !1}
23+
!llvm.ident = !{!2, !2, !2, !2, !2, !2, !2, !2, !2, !2, !2}
24+
!llvm.module.flags = !{!3, !4}
25+
26+
!0 = !{i32 1, i32 2}
27+
!1 = !{i32 4, i32 100000}
28+
!2 = !{!"clang version 13.0.0 (https://github.com/intel/llvm)"}
29+
!3 = !{i32 1, !"wchar_size", i32 4}
30+
!4 = !{i32 7, !"frame-pointer", i32 2}
31+
32+
; Confirm the decorations for the functions
33+
; CHECK-IR-DAG: [[MD_TRUE]] = !{i32 1}

sycl/include/CL/__spirv/spirv_ops.hpp

+19
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,25 @@ extern __DPCPP_SYCL_EXTERNAL
12671267
std::enable_if_t<std::is_integral_v<to> && std::is_unsigned_v<to>, to>
12681268
__spirv_ConvertPtrToU(from val) noexcept;
12691269

1270+
template <typename RetT, typename... ArgsT>
1271+
extern __DPCPP_SYCL_EXTERNAL __spv::__spirv_TaskSequenceINTEL *
1272+
__spirv_TaskSequenceCreateINTEL(RetT (*f)(ArgsT...), int Pipelined = -1,
1273+
int ClusterMode = -1,
1274+
unsigned int ResponseCapacity = 0,
1275+
unsigned int InvocationCapacity = 0) noexcept;
1276+
1277+
template <typename... ArgsT>
1278+
extern __DPCPP_SYCL_EXTERNAL void
1279+
__spirv_TaskSequenceAsyncINTEL(__spv::__spirv_TaskSequenceINTEL *TaskSequence,
1280+
ArgsT... Args) noexcept;
1281+
1282+
template <typename RetT>
1283+
extern __DPCPP_SYCL_EXTERNAL RetT __spirv_TaskSequenceGetINTEL(
1284+
__spv::__spirv_TaskSequenceINTEL *TaskSequence) noexcept;
1285+
1286+
extern __DPCPP_SYCL_EXTERNAL void __spirv_TaskSequenceReleaseINTEL(
1287+
__spv::__spirv_TaskSequenceINTEL *TaskSequence) noexcept;
1288+
12701289
#else // if !__SYCL_DEVICE_ONLY__
12711290

12721291
template <typename dataT>

sycl/include/CL/__spirv/spirv_types.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ template <typename T, std::size_t R, std::size_t C, MatrixLayout L,
124124
MatrixUse U = MatrixUse::MatrixA>
125125
struct __spirv_JointMatrixINTEL;
126126

127+
struct __spirv_TaskSequenceINTEL;
128+
127129
} // namespace __spv
128130

129131
#ifdef __SYCL_DEVICE_ONLY__

sycl/include/sycl/device_aspect_macros.hpp

+10
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,11 @@
318318
#define __SYCL_ALL_DEVICES_HAVE_ext_oneapi_graph__ 0
319319
#endif
320320

321+
#ifndef __SYCL_ALL_DEVICES_HAVE_ext_intel_fpga_task_sequence__
322+
// __SYCL_ASPECT(ext_intel_fpga_task_sequence, 62)
323+
#define __SYCL_ALL_DEVICES_HAVE_ext_intel_fpga_task_sequence__ 0
324+
#endif
325+
321326
#ifndef __SYCL_ANY_DEVICE_HAS_host__
322327
// __SYCL_ASPECT(host, 0)
323328
#define __SYCL_ANY_DEVICE_HAS_host__ 0
@@ -627,3 +632,8 @@
627632
// __SYCL_ASPECT(ext_oneapi_graph, 61)
628633
#define __SYCL_ANY_DEVICE_HAS_ext_oneapi_graph__ 0
629634
#endif
635+
636+
#ifndef __SYCL_ANY_DEVICE_HAS_ext_intel_fpga_task_sequence__
637+
// __SYCL_ASPECT(ext_intel_fpga_task_sequence__, 62)
638+
#define __SYCL_ANY_DEVICE_HAS_ext_intel_fpga_task_sequence__ 0
639+
#endif

sycl/include/sycl/ext/intel/experimental/fpga_kernel_properties.hpp

+56-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//==----- fpga_kernel_properties.hpp - SYCL properties associated with FPGA
2-
// kernel properties ---==//
1+
//===--------------------- fpga_kernel_properties.hpp ---------------------===//
2+
// SYCL properties associated with FPGA kernel properties
33
//
44
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
55
// See https://llvm.org/LICENSE.txt for license information.
@@ -12,11 +12,15 @@
1212
#include <sycl/ext/oneapi/properties/property.hpp>
1313
#include <sycl/ext/oneapi/properties/property_value.hpp>
1414

15+
#include <cstdint> // for uint16_t
16+
#include <type_traits> // for true_type
17+
1518
namespace sycl {
1619
inline namespace _V1 {
1720
namespace ext::intel::experimental {
1821

1922
template <typename T, typename PropertyListT> class fpga_kernel_attribute;
23+
template <auto &f, typename PropertyListT> class task_sequence;
2024

2125
enum class streaming_interface_options_enum : std::uint16_t {
2226
accept_downstream_stall,
@@ -28,6 +32,11 @@ enum class register_map_interface_options_enum : std::uint16_t {
2832
wait_for_done_write,
2933
};
3034

35+
enum class fpga_cluster_options_enum : std::uint16_t {
36+
stall_free,
37+
stall_enable
38+
};
39+
3140
struct streaming_interface_key
3241
: oneapi::experimental::detail::compile_time_property_key<
3342
oneapi::experimental::detail::PropKind::StreamingInterface> {
@@ -54,6 +63,15 @@ struct pipelined_key : oneapi::experimental::detail::compile_time_property_key<
5463
std::integral_constant<int, pipeline_directive_or_initiation_interval>>;
5564
};
5665

66+
struct fpga_cluster_key
67+
: oneapi::experimental::detail::compile_time_property_key<
68+
oneapi::experimental::detail::PropKind::FPGACluster> {
69+
template <fpga_cluster_options_enum option>
70+
using value_t = ext::oneapi::experimental::property_value<
71+
fpga_cluster_key,
72+
std::integral_constant<fpga_cluster_options_enum, option>>;
73+
};
74+
5775
template <streaming_interface_options_enum option =
5876
streaming_interface_options_enum::accept_downstream_stall>
5977
inline constexpr streaming_interface_key::value_t<option> streaming_interface;
@@ -84,6 +102,18 @@ inline constexpr pipelined_key::value_t<
84102
pipeline_directive_or_initiation_interval>
85103
pipelined;
86104

105+
template <fpga_cluster_options_enum option =
106+
fpga_cluster_options_enum::stall_free>
107+
inline constexpr fpga_cluster_key::value_t<option> fpga_cluster;
108+
109+
inline constexpr fpga_cluster_key::value_t<
110+
fpga_cluster_options_enum::stall_free>
111+
stall_free_clusters;
112+
113+
inline constexpr fpga_cluster_key::value_t<
114+
fpga_cluster_options_enum::stall_enable>
115+
stall_enable_clusters;
116+
87117
} // namespace ext::intel::experimental
88118

89119
namespace ext::oneapi::experimental {
@@ -103,6 +133,22 @@ struct is_property_key_of<
103133
intel::experimental::fpga_kernel_attribute<T, PropertyListT>>
104134
: std::true_type {};
105135

136+
template <typename T, typename PropertyListT>
137+
struct is_property_key_of<
138+
intel::experimental::fpga_cluster_key,
139+
intel::experimental::fpga_kernel_attribute<T, PropertyListT>>
140+
: std::true_type {};
141+
142+
template <auto &f, typename PropertyListT>
143+
struct is_property_key_of<intel::experimental::pipelined_key,
144+
intel::experimental::task_sequence<f, PropertyListT>>
145+
: std::true_type {};
146+
147+
template <auto &f, typename PropertyListT>
148+
struct is_property_key_of<intel::experimental::fpga_cluster_key,
149+
intel::experimental::task_sequence<f, PropertyListT>>
150+
: std::true_type {};
151+
106152
namespace detail {
107153
template <intel::experimental::streaming_interface_options_enum Stall_Free>
108154
struct PropertyMetaInfo<
@@ -124,6 +170,14 @@ struct PropertyMetaInfo<intel::experimental::pipelined_key::value_t<Value>> {
124170
static constexpr int value = Value;
125171
};
126172

173+
template <intel::experimental::fpga_cluster_options_enum ClusterType>
174+
struct PropertyMetaInfo<
175+
intel::experimental::fpga_cluster_key::value_t<ClusterType>> {
176+
static constexpr const char *name = "sycl-fpga-cluster";
177+
static constexpr intel::experimental::fpga_cluster_options_enum value =
178+
ClusterType;
179+
};
180+
127181
} // namespace detail
128182
} // namespace ext::oneapi::experimental
129183
} // namespace _V1

0 commit comments

Comments
 (0)