Skip to content

Commit 1f0b436

Browse files
committed
[spirv] Move device info from resource limit into target env
Vendor/device information are not resource limits. Moving to target environment directly for better organization. Reviewed By: mravishankar Differential Revision: https://reviews.llvm.org/D87911
1 parent 9932561 commit 1f0b436

File tree

9 files changed

+163
-41
lines changed

9 files changed

+163
-41
lines changed

mlir/docs/Dialects/SPIR-V.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,8 +805,14 @@ spirv-vce-attribute ::= `#` `spv.vce` `<`
805805
spirv-capability-list `,`
806806
spirv-extensions-list `>`
807807
808+
spirv-vendor-id ::= `AMD` | `NVIDIA` | ...
809+
spirv-device-type ::= `DiscreteGPU` | `IntegratedGPU` | `CPU` | ...
810+
spirv-device-id ::= integer-literal
811+
spirv-device-info ::= spirv-vendor-id (`:` spirv-device-type (`:` spirv-device-id)?)?
812+
808813
spirv-target-env-attribute ::= `#` `spv.target_env` `<`
809814
spirv-vce-attribute,
815+
(spirv-device-info `,`)?
810816
spirv-resource-limits `>`
811817
```
812818

@@ -827,6 +833,7 @@ For example,
827833
module attributes {
828834
spv.target_env = #spv.target_env<
829835
#spv.vce<v1.3, [Shader, GroupNonUniform], [SPV_KHR_8bit_storage]>,
836+
ARM:IntegratedGPU,
830837
{
831838
max_compute_workgroup_invocations = 128 : i32,
832839
max_compute_workgroup_size = dense<[128, 128, 64]> : vector<3xi32>

mlir/include/mlir/Dialect/SPIRV/SPIRVAttributes.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
namespace mlir {
2424
namespace spirv {
2525
enum class Capability : uint32_t;
26+
enum class DeviceType;
2627
enum class Extension;
28+
enum class Vendor;
2729
enum class Version : uint32_t;
2830

2931
namespace detail {
@@ -123,10 +125,15 @@ class TargetEnvAttr
123125
: public Attribute::AttrBase<TargetEnvAttr, Attribute,
124126
detail::TargetEnvAttributeStorage> {
125127
public:
128+
/// ID for unknown devices.
129+
static constexpr uint32_t kUnknownDeviceID = 0x7FFFFFFF;
130+
126131
using Base::Base;
127132

128133
/// Gets a TargetEnvAttr instance.
129-
static TargetEnvAttr get(VerCapExtAttr triple, DictionaryAttr limits);
134+
static TargetEnvAttr get(VerCapExtAttr triple, Vendor vendorID,
135+
DeviceType deviceType, uint32_t deviceId,
136+
DictionaryAttr limits);
130137

131138
/// Returns the attribute kind's name (without the 'spv.' prefix).
132139
static StringRef getKindName();
@@ -147,12 +154,22 @@ class TargetEnvAttr
147154
/// Returns the target capabilities as an integer array attribute.
148155
ArrayAttr getCapabilitiesAttr();
149156

157+
/// Returns the vendor ID.
158+
Vendor getVendorID();
159+
160+
/// Returns the device type.
161+
DeviceType getDeviceType();
162+
163+
/// Returns the device ID.
164+
uint32_t getDeviceID();
165+
150166
/// Returns the target resource limits.
151167
ResourceLimitsAttr getResourceLimits();
152168

153-
static LogicalResult verifyConstructionInvariants(Location loc,
154-
VerCapExtAttr triple,
155-
DictionaryAttr limits);
169+
static LogicalResult
170+
verifyConstructionInvariants(Location loc, VerCapExtAttr triple,
171+
Vendor vendorID, DeviceType deviceType,
172+
uint32_t deviceID, DictionaryAttr limits);
156173
};
157174
} // namespace spirv
158175
} // namespace mlir

mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -254,20 +254,36 @@ def QueryCapabilityInterface : SPIRVOpInterface<"QueryCapabilityInterface"> {
254254
// SPIR-V target GPU vendor and device definitions
255255
//===----------------------------------------------------------------------===//
256256

257+
def SPV_DT_CPU : StrEnumAttrCase<"CPU">;
258+
def SPV_DT_DiscreteGPU : StrEnumAttrCase<"DiscreteGPU">;
259+
def SPV_DT_IntegratedGPU : StrEnumAttrCase<"IntegratedGPU">;
257260
// An accelerator other than GPU or CPU
258-
def SPV_DT_Other : I32EnumAttrCase<"Other", 0>;
259-
def SPV_DT_IntegratedGPU : I32EnumAttrCase<"IntegratedGPU", 1>;
260-
def SPV_DT_DiscreteGPU : I32EnumAttrCase<"DiscreteGPU", 2>;
261-
def SPV_DT_CPU : I32EnumAttrCase<"CPU", 3>;
261+
def SPV_DT_Other : StrEnumAttrCase<"Other">;
262262
// Information missing.
263-
def SPV_DT_Unknown : I32EnumAttrCase<"Unknown", 0x7FFFFFFF>;
263+
def SPV_DT_Unknown : StrEnumAttrCase<"Unknown">;
264264

265-
def SPV_DeviceTypeAttr : SPV_I32EnumAttr<
265+
def SPV_DeviceTypeAttr : SPV_StrEnumAttr<
266266
"DeviceType", "valid SPIR-V device types", [
267267
SPV_DT_Other, SPV_DT_IntegratedGPU, SPV_DT_DiscreteGPU,
268268
SPV_DT_CPU, SPV_DT_Unknown
269269
]>;
270270

271+
def SPV_V_AMD : StrEnumAttrCase<"AMD">;
272+
def SPV_V_ARM : StrEnumAttrCase<"ARM">;
273+
def SPV_V_Imagination : StrEnumAttrCase<"Imagination">;
274+
def SPV_V_Intel : StrEnumAttrCase<"Intel">;
275+
def SPV_V_NVIDIA : StrEnumAttrCase<"NVIDIA">;
276+
def SPV_V_Qualcomm : StrEnumAttrCase<"Qualcomm">;
277+
def SPV_V_SwiftShader : StrEnumAttrCase<"SwiftShader">;
278+
def SPV_V_Unknown : StrEnumAttrCase<"Unknown">;
279+
280+
def SPV_VendorAttr : SPV_StrEnumAttr<
281+
"Vendor", "recognized SPIR-V vendor strings", [
282+
SPV_V_AMD, SPV_V_ARM, SPV_V_Imagination, SPV_V_Intel,
283+
SPV_V_NVIDIA, SPV_V_Qualcomm, SPV_V_SwiftShader,
284+
SPV_V_Unknown
285+
]>;
286+
271287
//===----------------------------------------------------------------------===//
272288
// SPIR-V extension definitions
273289
//===----------------------------------------------------------------------===//

mlir/include/mlir/Dialect/SPIRV/TargetAndABI.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ class TargetEnv {
2929
public:
3030
explicit TargetEnv(TargetEnvAttr targetAttr);
3131

32-
DeviceType getDeviceType();
33-
3432
Version getVersion();
3533

3634
/// Returns true if the given capability is allowed.

mlir/include/mlir/Dialect/SPIRV/TargetAndABI.td

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,6 @@ def SPV_CapabilityArrayAttr : TypedArrayAttrBase<
4545
// are the from Vulkan limit requirements:
4646
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#limits-minmax
4747
def SPV_ResourceLimitsAttr : StructAttr<"ResourceLimitsAttr", SPIRV_Dialect, [
48-
// Unique identifier for the vendor and target GPU.
49-
// 0x7FFFFFFF means unknown.
50-
StructFieldAttr<"vendor_id", DefaultValuedAttr<I32Attr, "0x7FFFFFFF">>,
51-
StructFieldAttr<"device_id", DefaultValuedAttr<I32Attr, "0x7FFFFFFF">>,
52-
// Target device type.
53-
StructFieldAttr<"device_type",
54-
DefaultValuedAttr<SPV_DeviceTypeAttr,
55-
"::mlir::spirv::DeviceType::Unknown">>,
56-
5748
// The maximum total storage size, in bytes, available for variables
5849
// declared with the Workgroup storage class.
5950
StructFieldAttr<"max_compute_shared_memory_size",

mlir/lib/Dialect/SPIRV/SPIRVAttributes.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,23 +77,32 @@ struct VerCapExtAttributeStorage : public AttributeStorage {
7777
};
7878

7979
struct TargetEnvAttributeStorage : public AttributeStorage {
80-
using KeyTy = std::pair<Attribute, Attribute>;
80+
using KeyTy = std::tuple<Attribute, Vendor, DeviceType, uint32_t, Attribute>;
8181

82-
TargetEnvAttributeStorage(Attribute triple, Attribute limits)
83-
: triple(triple), limits(limits) {}
82+
TargetEnvAttributeStorage(Attribute triple, Vendor vendorID,
83+
DeviceType deviceType, uint32_t deviceID,
84+
Attribute limits)
85+
: triple(triple), limits(limits), vendorID(vendorID),
86+
deviceType(deviceType), deviceID(deviceID) {}
8487

8588
bool operator==(const KeyTy &key) const {
86-
return key.first == triple && key.second == limits;
89+
return key ==
90+
std::make_tuple(triple, vendorID, deviceType, deviceID, limits);
8791
}
8892

8993
static TargetEnvAttributeStorage *
9094
construct(AttributeStorageAllocator &allocator, const KeyTy &key) {
9195
return new (allocator.allocate<TargetEnvAttributeStorage>())
92-
TargetEnvAttributeStorage(key.first, key.second);
96+
TargetEnvAttributeStorage(std::get<0>(key), std::get<1>(key),
97+
std::get<2>(key), std::get<3>(key),
98+
std::get<4>(key));
9399
}
94100

95101
Attribute triple;
96102
Attribute limits;
103+
Vendor vendorID;
104+
DeviceType deviceType;
105+
uint32_t deviceID;
97106
};
98107
} // namespace detail
99108
} // namespace spirv
@@ -268,10 +277,13 @@ LogicalResult spirv::VerCapExtAttr::verifyConstructionInvariants(
268277
//===----------------------------------------------------------------------===//
269278

270279
spirv::TargetEnvAttr spirv::TargetEnvAttr::get(spirv::VerCapExtAttr triple,
280+
Vendor vendorID,
281+
DeviceType deviceType,
282+
uint32_t deviceID,
271283
DictionaryAttr limits) {
272284
assert(triple && limits && "expected valid triple and limits");
273285
MLIRContext *context = triple.getContext();
274-
return Base::get(context, triple, limits);
286+
return Base::get(context, triple, vendorID, deviceType, deviceID, limits);
275287
}
276288

277289
StringRef spirv::TargetEnvAttr::getKindName() { return "target_env"; }
@@ -300,12 +312,24 @@ ArrayAttr spirv::TargetEnvAttr::getCapabilitiesAttr() {
300312
return getTripleAttr().getCapabilitiesAttr();
301313
}
302314

315+
spirv::Vendor spirv::TargetEnvAttr::getVendorID() {
316+
return getImpl()->vendorID;
317+
}
318+
319+
spirv::DeviceType spirv::TargetEnvAttr::getDeviceType() {
320+
return getImpl()->deviceType;
321+
}
322+
323+
uint32_t spirv::TargetEnvAttr::getDeviceID() { return getImpl()->deviceID; }
324+
303325
spirv::ResourceLimitsAttr spirv::TargetEnvAttr::getResourceLimits() {
304326
return getImpl()->limits.cast<spirv::ResourceLimitsAttr>();
305327
}
306328

307329
LogicalResult spirv::TargetEnvAttr::verifyConstructionInvariants(
308-
Location loc, spirv::VerCapExtAttr triple, DictionaryAttr limits) {
330+
Location loc, spirv::VerCapExtAttr /*triple*/, spirv::Vendor /*vendorID*/,
331+
spirv::DeviceType /*deviceType*/, uint32_t /*deviceID*/,
332+
DictionaryAttr limits) {
309333
if (!limits.isa<spirv::ResourceLimitsAttr>())
310334
return emitError(loc, "expected spirv::ResourceLimitsAttr for limits");
311335

mlir/lib/Dialect/SPIRV/SPIRVDialect.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,42 @@ static Attribute parseTargetEnvAttr(DialectAsmParser &parser) {
918918
if (parser.parseAttribute(tripleAttr) || parser.parseComma())
919919
return {};
920920

921+
// Parse [vendor[:device-type[:device-id]]]
922+
Vendor vendorID = Vendor::Unknown;
923+
DeviceType deviceType = DeviceType::Unknown;
924+
uint32_t deviceID = spirv::TargetEnvAttr::kUnknownDeviceID;
925+
{
926+
auto loc = parser.getCurrentLocation();
927+
StringRef vendorStr;
928+
if (succeeded(parser.parseOptionalKeyword(&vendorStr))) {
929+
if (auto vendorSymbol = spirv::symbolizeVendor(vendorStr)) {
930+
vendorID = *vendorSymbol;
931+
} else {
932+
parser.emitError(loc, "unknown vendor: ") << vendorStr;
933+
}
934+
935+
if (succeeded(parser.parseOptionalColon())) {
936+
loc = parser.getCurrentLocation();
937+
StringRef deviceTypeStr;
938+
if (parser.parseKeyword(&deviceTypeStr))
939+
return {};
940+
if (auto deviceTypeSymbol = spirv::symbolizeDeviceType(deviceTypeStr)) {
941+
deviceType = *deviceTypeSymbol;
942+
} else {
943+
parser.emitError(loc, "unknown device type: ") << deviceTypeStr;
944+
}
945+
946+
if (succeeded(parser.parseOptionalColon())) {
947+
loc = parser.getCurrentLocation();
948+
if (parser.parseInteger(deviceID))
949+
return {};
950+
}
951+
}
952+
if (parser.parseComma())
953+
return {};
954+
}
955+
}
956+
921957
DictionaryAttr limitsAttr;
922958
{
923959
auto loc = parser.getCurrentLocation();
@@ -937,7 +973,8 @@ static Attribute parseTargetEnvAttr(DialectAsmParser &parser) {
937973
if (parser.parseGreater())
938974
return {};
939975

940-
return spirv::TargetEnvAttr::get(tripleAttr, limitsAttr);
976+
return spirv::TargetEnvAttr::get(tripleAttr, vendorID, deviceType, deviceID,
977+
limitsAttr);
941978
}
942979

943980
Attribute SPIRVDialect::parseAttribute(DialectAsmParser &parser,
@@ -986,6 +1023,17 @@ static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer) {
9861023
static void print(spirv::TargetEnvAttr targetEnv, DialectAsmPrinter &printer) {
9871024
printer << spirv::TargetEnvAttr::getKindName() << "<#spv.";
9881025
print(targetEnv.getTripleAttr(), printer);
1026+
spirv::Vendor vendorID = targetEnv.getVendorID();
1027+
spirv::DeviceType deviceType = targetEnv.getDeviceType();
1028+
uint32_t deviceID = targetEnv.getDeviceID();
1029+
if (vendorID != spirv::Vendor::Unknown) {
1030+
printer << ", " << spirv::stringifyVendor(vendorID);
1031+
if (deviceType != spirv::DeviceType::Unknown) {
1032+
printer << ":" << spirv::stringifyDeviceType(deviceType);
1033+
if (deviceID != spirv::TargetEnvAttr::kUnknownDeviceID)
1034+
printer << ":" << deviceID;
1035+
}
1036+
}
9891037
printer << ", " << targetEnv.getResourceLimits() << ">";
9901038
}
9911039

mlir/lib/Dialect/SPIRV/TargetAndABI.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,6 @@ spirv::TargetEnv::TargetEnv(spirv::TargetEnvAttr targetAttr)
3838
}
3939
}
4040

41-
spirv::DeviceType spirv::TargetEnv::getDeviceType() {
42-
auto deviceType = spirv::symbolizeDeviceType(
43-
targetAttr.getResourceLimits().device_type().getInt());
44-
if (!deviceType)
45-
return DeviceType::Unknown;
46-
return *deviceType;
47-
}
48-
4941
spirv::Version spirv::TargetEnv::getVersion() {
5042
return targetAttr.getVersion();
5143
}
@@ -145,9 +137,6 @@ spirv::getDefaultResourceLimits(MLIRContext *context) {
145137
// All the fields have default values. Here we just provide a nicer way to
146138
// construct a default resource limit attribute.
147139
return spirv::ResourceLimitsAttr ::get(
148-
/*vendor_id=*/nullptr,
149-
/*device_id*/ nullptr,
150-
/*device_type=*/nullptr,
151140
/*max_compute_shared_memory_size=*/nullptr,
152141
/*max_compute_workgroup_invocations=*/nullptr,
153142
/*max_compute_workgroup_size=*/nullptr,
@@ -160,7 +149,9 @@ spirv::TargetEnvAttr spirv::getDefaultTargetEnv(MLIRContext *context) {
160149
auto triple = spirv::VerCapExtAttr::get(spirv::Version::V_1_0,
161150
{spirv::Capability::Shader},
162151
ArrayRef<Extension>(), context);
163-
return spirv::TargetEnvAttr::get(triple,
152+
return spirv::TargetEnvAttr::get(triple, spirv::Vendor::Unknown,
153+
spirv::DeviceType::Unknown,
154+
spirv::TargetEnvAttr::kUnknownDeviceID,
164155
spirv::getDefaultResourceLimits(context));
165156
}
166157

mlir/test/Dialect/SPIRV/target-and-abi.mlir

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,36 @@ func @target_env() attributes {
127127

128128
// -----
129129

130+
func @target_env_vendor_id() attributes {
131+
// CHECK: spv.target_env = #spv.target_env<
132+
// CHECK-SAME: #spv.vce<v1.0, [], []>,
133+
// CHECK-SAME: NVIDIA,
134+
// CHECK-SAME: {}>
135+
spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, NVIDIA, {}>
136+
} { return }
137+
138+
// -----
139+
140+
func @target_env_vendor_id_device_type() attributes {
141+
// CHECK: spv.target_env = #spv.target_env<
142+
// CHECK-SAME: #spv.vce<v1.0, [], []>,
143+
// CHECK-SAME: AMD:DiscreteGPU,
144+
// CHECK-SAME: {}>
145+
spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, AMD:DiscreteGPU, {}>
146+
} { return }
147+
148+
// -----
149+
150+
func @target_env_vendor_id_device_type_device_id() attributes {
151+
// CHECK: spv.target_env = #spv.target_env<
152+
// CHECK-SAME: #spv.vce<v1.0, [], []>,
153+
// CHECK-SAME: Qualcomm:IntegratedGPU:100925441,
154+
// CHECK-SAME: {}>
155+
spv.target_env = #spv.target_env<#spv.vce<v1.0, [], []>, Qualcomm:IntegratedGPU:0x6040001, {}>
156+
} { return }
157+
158+
// -----
159+
130160
func @target_env_extra_fields() attributes {
131161
// expected-error @+6 {{expected '>'}}
132162
spv.target_env = #spv.target_env<

0 commit comments

Comments
 (0)