Skip to content

Commit 370aa2a

Browse files
authored
[SYCL] Add experimental implementation of sycl_ext_intel_grf_size (#9882)
This change implements `sycl_ext_intel_grf_size`, and in particular: 1) Moves the `sycl_ext_intel_grf_size` spec document from the `proposed` folder to the `experimental` folder, and updates the implementation status in the document to match. 2) Adds two new kernel properties `sycl::ext::intel::experimental::grf_size` and `sycl::ext::intel::experimental::grf_size_automatic`, as per the spec. `grf_size` adds the `sycl-grf-size` metadata with a value of the template parameter (`128` or `256`). `grf_size_automatic` adds the `sycl-grf-size` metadata with a value of `0`. 3) Marks the `sycl::detail::register_alloc_mode` property as deprecated, and it still works as before. 4) Updates `CompileTimePropertiesPass.cpp` to map the `sycl-grf-size` metadata added by the front-end to the `RegisterAllocMode` metadata which `llvm-spirv` looks for. This `RegisterAllocMode` metadata is how AOT works. 5) Updates `sycl-post-link` to split by the `sycl-grf-size` metadata, have a `sycl-grf-size` binary property, and do a error check to make sure the deprecated `sycl::detail::register_alloc_mode` and `grf_size`/`grf_size_automatic` are not set at the same time on the same kernel. 6) Updates `program_manager` to deal with the new image property and pass the right flags 7) Updates exists tests to also test the new properties. --------- Signed-off-by: Sarnie, Nick <[email protected]>
1 parent 58a8f20 commit 370aa2a

File tree

17 files changed

+391
-28
lines changed

17 files changed

+391
-28
lines changed

llvm/lib/SYCLLowerIR/CompileTimePropertiesPass.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace {
2929
constexpr StringRef SYCL_HOST_ACCESS_ATTR = "sycl-host-access";
3030
constexpr StringRef SYCL_PIPELINED_ATTR = "sycl-pipelined";
3131
constexpr StringRef SYCL_REGISTER_ALLOC_MODE_ATTR = "sycl-register-alloc-mode";
32+
constexpr StringRef SYCL_GRF_SIZE_ATTR = "sycl-grf-size";
3233

3334
constexpr StringRef SPIRV_DECOR_MD_KIND = "spirv.Decorations";
3435
constexpr StringRef SPIRV_PARAM_DECOR_MD_KIND = "spirv.ParameterDecorations";
@@ -270,11 +271,24 @@ attributeToExecModeMetadata(const Attribute &Attr, Function &F) {
270271
return std::pair<std::string, MDNode *>("ip_interface",
271272
getIpInterface("csr", Ctx, Attr));
272273

273-
if (AttrKindStr == SYCL_REGISTER_ALLOC_MODE_ATTR &&
274+
if ((AttrKindStr == SYCL_REGISTER_ALLOC_MODE_ATTR ||
275+
AttrKindStr == SYCL_GRF_SIZE_ATTR) &&
274276
!llvm::esimd::isESIMD(F)) {
275-
uint32_t RegAllocModeVal = getAttributeAsInteger<uint32_t>(Attr);
276-
Metadata *AttrMDArgs[] = {ConstantAsMetadata::get(Constant::getIntegerValue(
277-
Type::getInt32Ty(Ctx), APInt(32, RegAllocModeVal)))};
277+
// TODO: Remove SYCL_REGISTER_ALLOC_MODE_ATTR support in next ABI break.
278+
uint32_t PropVal = getAttributeAsInteger<uint32_t>(Attr);
279+
if (AttrKindStr == SYCL_GRF_SIZE_ATTR) {
280+
assert((PropVal == 0 || PropVal == 128 || PropVal == 256) &&
281+
"Unsupported GRF Size");
282+
// Map sycl-grf-size values to RegisterAllocMode values used in SPIR-V.
283+
static constexpr int SMALL_GRF_REGALLOCMODE_VAL = 1;
284+
static constexpr int LARGE_GRF_REGALLOCMODE_VAL = 2;
285+
if (PropVal == 128)
286+
PropVal = SMALL_GRF_REGALLOCMODE_VAL;
287+
else if (PropVal == 256)
288+
PropVal = LARGE_GRF_REGALLOCMODE_VAL;
289+
}
290+
Metadata *AttrMDArgs[] = {ConstantAsMetadata::get(
291+
Constant::getIntegerValue(Type::getInt32Ty(Ctx), APInt(32, PropVal)))};
278292
return std::pair<std::string, MDNode *>("RegisterAllocMode",
279293
MDNode::get(Ctx, AttrMDArgs));
280294
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; Check we create RegisterAllocMode metadata if there is a non-ESIMD kernel with that property
2+
; RUN: opt -passes=compile-time-properties %s -S | FileCheck %s --check-prefix CHECK-IR
3+
4+
; Function Attrs: convergent norecurse
5+
define weak_odr dso_local spir_kernel void @sycl_grf_size() #1 {
6+
; CHECK-IR-NOT: !RegisterAllocMode
7+
; CHECK-IR: sycl_grf_size() #[[#Attr1:]]{{.*}}!RegisterAllocMode ![[#MDVal:]] {
8+
; CHECK-IR-NOT: !RegisterAllocMode
9+
; CHECK-IR: ![[#MDVal]] = !{i32 2}
10+
entry:
11+
ret void
12+
}
13+
14+
; Function Attrs: convergent norecurse
15+
define weak_odr dso_local spir_kernel void @sycl_no_grf_size() #0 {
16+
entry:
17+
ret void
18+
}
19+
20+
; Function Attrs: convergent norecurse
21+
define weak_odr dso_local spir_kernel void @esimd_grf_size() #1 !sycl_explicit_simd !1 {
22+
entry:
23+
ret void
24+
}
25+
26+
; Function Attrs: convergent norecurse
27+
define weak_odr dso_local spir_kernel void @esimd_no_grf_size() #0 {
28+
entry:
29+
ret void
30+
}
31+
32+
attributes #0 = { convergent norecurse }
33+
attributes #1 = { convergent norecurse "sycl-grf-size"="256" }
34+
35+
!1 = !{}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; This test confirms an error with sycl-register-alloc-mode and sycl-grf-size on the same kernel.
2+
3+
; RUN: not sycl-post-link -split=source -symbols -split-esimd -lower-esimd -S < %s 2>&1 | FileCheck %s
4+
5+
; CHECK: Unsupported use of both register_alloc_mode and grf_size
6+
7+
source_filename = "llvm-link"
8+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
9+
target triple = "spir64-unknown-unknown"
10+
11+
define weak_odr dso_local spir_kernel void @__SYCL_kernel() #0 {
12+
entry:
13+
ret void
14+
}
15+
16+
attributes #0 = { "sycl-module-id"="a.cpp" "sycl-grf-size"="256" "sycl-register-alloc-mode"="0"}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
; This test checks handling of sycl-grf-size in SYCL post link
2+
3+
; RUN: sycl-post-link -split=source -symbols -split-esimd -lower-esimd -S < %s -o %t.table
4+
; RUN: FileCheck %s -input-file=%t.table
5+
; RUN: FileCheck %s -input-file=%t_esimd_0.ll --check-prefixes CHECK-ESIMD-LargeGRF-IR --implicit-check-not='__ESIMD_kernel()'
6+
; RUN: FileCheck %s -input-file=%t_esimd_0.prop --check-prefixes CHECK-ESIMD-LargeGRF-PROP
7+
; RUN: FileCheck %s -input-file=%t_esimd_0.sym --check-prefixes CHECK-ESIMD-LargeGRF-SYM
8+
; RUN: FileCheck %s -input-file=%t_1.ll --check-prefixes CHECK-SYCL-LargeGRF-IR --implicit-check-not='__SYCL_kernel()'
9+
; RUN: FileCheck %s -input-file=%t_1.prop --check-prefixes CHECK-SYCL-LargeGRF-PROP
10+
; RUN: FileCheck %s -input-file=%t_1.sym --check-prefixes CHECK-SYCL-LargeGRF-SYM
11+
; RUN: FileCheck %s -input-file=%t_3.ll --check-prefixes CHECK-SYCL-IR --implicit-check-not='__SYCL_kernel_large_grf()'
12+
; RUN: FileCheck %s -input-file=%t_3.prop --check-prefixes CHECK-SYCL-PROP
13+
; RUN: FileCheck %s -input-file=%t_3.sym --check-prefixes CHECK-SYCL-SYM
14+
; RUN: FileCheck %s -input-file=%t_esimd_2.ll --check-prefixes CHECK-ESIMD-IR --implicit-check-not='__ESIMD_large_grf_kernel()'
15+
; RUN: FileCheck %s -input-file=%t_esimd_2.prop --check-prefixes CHECK-ESIMD-PROP
16+
17+
; CHECK: [Code|Properties|Symbols]
18+
; CHECK: {{.*}}_esimd_0.ll|{{.*}}_esimd_0.prop|{{.*}}_esimd_0.sym
19+
; CHECK: {{.*}}_1.ll|{{.*}}_1.prop|{{.*}}_1.sym
20+
; CHECK: {{.*}}_esimd_2.ll|{{.*}}_esimd_2.prop|{{.*}}_esimd_2.sym
21+
22+
; CHECK-ESIMD-LargeGRF-PROP: isEsimdImage=1|1
23+
; CHECK-ESIMD-LargeGRF-PROP: sycl-grf-size=1|256
24+
25+
; CHECK-SYCL-LargeGRF-PROP: sycl-grf-size=1|256
26+
27+
; CHECK-SYCL-LargeGRF-IR: define {{.*}} spir_kernel void @__SYCL_kernel_large_grf() #[[SYCLAttr:]]
28+
; CHECK-SYCL-LargeGRF-IR: attributes #[[SYCLAttr]]
29+
30+
; CHECK-SYCL-PROP-NOT: sycl-grf-size
31+
32+
; CHECK-SYCL-SYM: __SYCL_kernel
33+
; CHECK-SYCL-SYM-EMPTY:
34+
35+
; CHECK-SYCL-IR: __SYCL_kernel() #[[SYCLAttr:]]
36+
; CHECK-SYCL-IR: attributes #[[SYCLAttr]]
37+
38+
; CHECK-SYCL-LargeGRF-SYM: __SYCL_kernel_large_grf
39+
; CHECK-SYCL-LargeGRF-SYM-EMPTY:
40+
41+
; CHECK-ESIMD-SYM: __ESIMD_kernel
42+
; CHECK-ESIMD-SYM-EMPTY:
43+
44+
; CHECK-ESIMD-IR: __ESIMD_kernel() #[[ESIMDAttr:]]
45+
; CHECK-ESIMD-IR: attributes #[[ESIMDAttr]]
46+
47+
; CHECK-ESIMD-PROP-NOT: sycl-grf-size
48+
49+
; CHECK-ESIMD-LargeGRF-SYM: __ESIMD_large_grf_kernel
50+
; CHECK-ESIMD-LargeGRF-SYM-EMPTY:
51+
52+
; CHECK-ESIMD-LargeGRF-IR: @__ESIMD_large_grf_kernel() #[[ESIMDLargeAttr:]]
53+
; CHECK-ESIMD-LargeGRF-IR: attributes #[[ESIMDLargeAttr]]
54+
55+
; ModuleID = 'large_grf.bc'
56+
source_filename = "grf"
57+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
58+
target triple = "spir64-unknown-unknown"
59+
60+
define weak_odr dso_local spir_kernel void @__SYCL_kernel() #0 {
61+
entry:
62+
ret void
63+
}
64+
65+
define weak_odr dso_local spir_kernel void @__SYCL_kernel_large_grf() #1 {
66+
entry:
67+
ret void
68+
}
69+
70+
define weak_odr dso_local spir_kernel void @__ESIMD_kernel() #0 !sycl_explicit_simd !0 !intel_reqd_sub_group_size !1 {
71+
entry:
72+
ret void
73+
}
74+
75+
define weak_odr dso_local spir_kernel void @__ESIMD_large_grf_kernel() #1 !sycl_explicit_simd !0 !intel_reqd_sub_group_size !1 {
76+
entry:
77+
ret void
78+
}
79+
80+
attributes #0 = { "sycl-module-id"="a.cpp" }
81+
attributes #1 = { "sycl-module-id"="a.cpp" "sycl-grf-size"="256" }
82+
83+
!0 = !{}
84+
!1 = !{i32 1}

llvm/tools/sycl-post-link/ModuleSplitter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,7 @@ getDeviceCodeSplitter(ModuleDesc &&MD, IRSplitMode Mode, bool IROutputOnly,
854854
// Note: Add more rules at the end of the list to avoid chaning orders of
855855
// output files in existing tests.
856856
Categorizer.registerSimpleStringAttributeRule("sycl-register-alloc-mode");
857+
Categorizer.registerSimpleStringAttributeRule("sycl-grf-size");
857858
Categorizer.registerListOfIntegersInMetadataSortedRule("sycl_used_aspects");
858859
Categorizer.registerListOfIntegersInMetadataRule("reqd_work_group_size");
859860
Categorizer.registerListOfIntegersInMetadataRule(

llvm/tools/sycl-post-link/sycl-post-link.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,12 +454,12 @@ std::string saveModuleProperties(module_split::ModuleDesc &MD,
454454
if (MD.isESIMD()) {
455455
PropSet[PropSetRegTy::SYCL_MISC_PROP].insert({"isEsimdImage", true});
456456
}
457-
457+
bool HasRegAllocMode = false;
458458
{
459459
StringRef RegAllocModeAttr = "sycl-register-alloc-mode";
460460
uint32_t RegAllocModeVal;
461461

462-
bool HasRegAllocMode = llvm::any_of(MD.entries(), [&](const Function *F) {
462+
HasRegAllocMode = llvm::any_of(MD.entries(), [&](const Function *F) {
463463
if (!F->hasFnAttribute(RegAllocModeAttr))
464464
return false;
465465
const auto &Attr = F->getFnAttribute(RegAllocModeAttr);
@@ -472,6 +472,25 @@ std::string saveModuleProperties(module_split::ModuleDesc &MD,
472472
}
473473
}
474474

475+
{
476+
StringRef GRFSizeAttr = "sycl-grf-size";
477+
uint32_t GRFSizeVal;
478+
479+
bool HasGRFSize = llvm::any_of(MD.entries(), [&](const Function *F) {
480+
if (!F->hasFnAttribute(GRFSizeAttr))
481+
return false;
482+
const auto &Attr = F->getFnAttribute(GRFSizeAttr);
483+
GRFSizeVal = getAttributeAsInteger<uint32_t>(Attr);
484+
return true;
485+
});
486+
if (HasGRFSize) {
487+
if (HasRegAllocMode)
488+
error("Unsupported use of both register_alloc_mode and "
489+
"grf_size");
490+
PropSet[PropSetRegTy::SYCL_MISC_PROP].insert({GRFSizeAttr, GRFSizeVal});
491+
}
492+
}
493+
475494
// FIXME: Remove 'if' below when possible
476495
// GPU backend has a problem with accepting optimization level options in form
477496
// described by Level Zero specification (-ze-opt-level=1) when 'invoke_simd'

sycl/doc/extensions/proposed/sycl_ext_intel_grf_size.asciidoc renamed to sycl/doc/extensions/experimental/sycl_ext_intel_grf_size.asciidoc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,11 @@ This extension also depends on the following other SYCL extensions:
4949

5050
== Status
5151

52-
This is a proposed extension specification, intended to gather community
53-
feedback. Interfaces defined in this specification may not be implemented yet
54-
or may be in a preliminary state. The specification itself may also change in
55-
incompatible ways before it is finalized. *Shipping software products should
56-
not rely on APIs defined in this specification.*
57-
52+
This is an experimental extension specification, intended to provide early access
53+
to features and gather community feedback. Interfaces defined in this specification
54+
are implemented in DPC++, but they are not finalized and may change incompatibly in
55+
future versions of DPC++ without prior notice. **Shipping software products should not
56+
rely on APIs defined in this specification.**
5857

5958
== Backend support status
6059

sycl/include/sycl/detail/kernel_properties.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ struct register_alloc_mode_key {
2929
};
3030

3131
template <register_alloc_mode_enum Mode>
32-
inline constexpr register_alloc_mode_key::value_t<Mode> register_alloc_mode;
32+
inline constexpr register_alloc_mode_key::value_t<Mode> register_alloc_mode
33+
__SYCL_DEPRECATED("register_alloc_mode is deprecated, "
34+
"use sycl::ext::intel::experimental::grf_size or "
35+
"sycl::ext::intel::experimental::grf_size_automatic");
3336
} // namespace detail
3437

3538
namespace ext::oneapi::experimental {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//==- grf_size_properties.hpp - GRF size kernel properties for Intel GPUs -==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===--------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include <sycl/ext/oneapi/properties/property.hpp>
12+
#include <sycl/ext/oneapi/properties/property_value.hpp>
13+
14+
#define SYCL_EXT_INTEL_GRF_SIZE 1
15+
16+
namespace sycl {
17+
__SYCL_INLINE_VER_NAMESPACE(_V1) {
18+
namespace ext::intel::experimental {
19+
struct grf_size_key {
20+
template <unsigned int Size>
21+
using value_t = oneapi::experimental::property_value<
22+
grf_size_key, std::integral_constant<unsigned int, Size>>;
23+
};
24+
25+
struct grf_size_automatic_key {
26+
using value_t = oneapi::experimental::property_value<grf_size_automatic_key>;
27+
};
28+
29+
template <unsigned int Size>
30+
inline constexpr grf_size_key::value_t<Size> grf_size;
31+
32+
inline constexpr grf_size_automatic_key::value_t grf_size_automatic;
33+
34+
} // namespace ext::intel::experimental
35+
namespace ext::oneapi::experimental {
36+
template <>
37+
struct is_property_key<sycl::ext::intel::experimental::grf_size_key>
38+
: std::true_type {};
39+
40+
template <>
41+
struct is_property_key<sycl::ext::intel::experimental::grf_size_automatic_key>
42+
: std::true_type {};
43+
44+
namespace detail {
45+
template <>
46+
struct PropertyToKind<sycl::ext::intel::experimental::grf_size_key> {
47+
static constexpr PropKind Kind = PropKind::GRFSize;
48+
};
49+
50+
template <>
51+
struct IsCompileTimeProperty<sycl::ext::intel::experimental::grf_size_key>
52+
: std::true_type {};
53+
54+
template <>
55+
struct PropertyToKind<sycl::ext::intel::experimental::grf_size_automatic_key> {
56+
static constexpr PropKind Kind = PropKind::GRFSizeAutomatic;
57+
};
58+
59+
template <>
60+
struct IsCompileTimeProperty<
61+
sycl::ext::intel::experimental::grf_size_automatic_key> : std::true_type {};
62+
63+
template <unsigned int Size>
64+
struct PropertyMetaInfo<
65+
sycl::ext::intel::experimental::grf_size_key::value_t<Size>> {
66+
static_assert(Size == 128 || Size == 256, "Unsupported GRF size");
67+
static constexpr const char *name = "sycl-grf-size";
68+
static constexpr unsigned int value = Size;
69+
};
70+
template <>
71+
struct PropertyMetaInfo<
72+
sycl::ext::intel::experimental::grf_size_automatic_key::value_t> {
73+
static constexpr const char *name = "sycl-grf-size";
74+
static constexpr unsigned int value = 0;
75+
};
76+
77+
template <typename Properties>
78+
struct ConflictingProperties<sycl::ext::intel::experimental::grf_size_key,
79+
Properties>
80+
: ContainsProperty<sycl::ext::intel::experimental::grf_size_automatic_key,
81+
Properties> {};
82+
83+
template <typename Properties>
84+
struct ConflictingProperties<
85+
sycl::ext::intel::experimental::grf_size_automatic_key, Properties>
86+
: ContainsProperty<sycl::ext::intel::experimental::grf_size_key,
87+
Properties> {};
88+
89+
} // namespace detail
90+
} // namespace ext::oneapi::experimental
91+
} // __SYCL_INLINE_VER_NAMESPACE(_V1)
92+
} // namespace sycl

sycl/include/sycl/ext/oneapi/properties/properties.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ template <typename PropertiesT> class properties {
131131
"Properties in property list are not sorted.");
132132
static_assert(detail::SortedAllUnique<PropertiesT>::value,
133133
"Duplicate properties in property list.");
134+
static_assert(detail::NoConflictingProperties<PropertiesT>::value,
135+
"Conflicting properties in property list.");
134136

135137
public:
136138
template <typename... PropertyValueTs>

sycl/include/sycl/ext/oneapi/properties/property.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,10 @@ enum PropKind : uint32_t {
195195
UsesValid = 29,
196196
UseRootSync = 30,
197197
RegisterAllocMode = 31,
198+
GRFSize = 32,
199+
GRFSizeAutomatic = 33,
198200
// PropKindSize must always be the last value.
199-
PropKindSize = 32,
201+
PropKindSize = 34,
200202
};
201203

202204
// This trait must be specialized for all properties and must have a unique

0 commit comments

Comments
 (0)