Skip to content

Commit

Permalink
DLTI: Simplifying getDevicePropertyValue API by returning Attribute t…
Browse files Browse the repository at this point in the history
…ype value (llvm#96706)

**Rationale**

- With the current flexibility of supporting any type of value, we will
need to offer type-specific APIs to fetch a value (e.g.,
`getDevicePropertyValueAsInt` for integer type,
`getDevicePropertyValueAsFloat` for float type, etc.) A single type of
value will eliminate this need.
- Current flexibility can also lead to typing errors when a user fetches
the value of a property using an API that is not consistent with the
type of the value.

**What is the change**

For following system description,


```
 module attributes {
   dlti.target_system_spec = #dlti.target_system_spec<
     "CPU": #dlti.target_device_spec<
      #dlti.dl_entry<"max_vector_op_width", 64.0 : f32>>,
     "GPU": #dlti.target_device_spec<
      #dlti.dl_entry<"max_vector_op_width", 128 : ui32>>
   >} {}
```

a user no longer needs to use `getDevicePropertyValueAsInt` for
retrieving GPU's `max_vector_op_width` and
`getDevicePropertyValueAsFloat` for retrieving CPU's
`max_vector_op_width`. Instead it can be done with a uniform API of
`getDevicePropertyValue`.
  • Loading branch information
nhasabni authored and AlexisPerry committed Jun 27, 2024
1 parent eaec0bf commit 849cea9
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 40 deletions.
9 changes: 4 additions & 5 deletions mlir/include/mlir/Interfaces/DataLayoutInterfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@ uint64_t getDefaultStackAlignment(DataLayoutEntryInterface entry);

/// Returns the value of the property from the specified DataLayoutEntry. If the
/// property is missing from the entry, returns std::nullopt.
std::optional<int64_t>
getDevicePropertyValueAsInt(DataLayoutEntryInterface entry);
std::optional<Attribute> getDevicePropertyValue(DataLayoutEntryInterface entry);

/// Given a list of data layout entries, returns a new list containing the
/// entries with keys having the given type ID, i.e. belonging to the same type
Expand Down Expand Up @@ -246,9 +245,9 @@ class DataLayout {

/// Returns the value of the specified property if the property is defined for
/// the given device ID, otherwise returns std::nullopt.
std::optional<int64_t>
getDevicePropertyValueAsInt(TargetSystemSpecInterface::DeviceID,
StringAttr propertyName) const;
std::optional<Attribute>
getDevicePropertyValue(TargetSystemSpecInterface::DeviceID,
StringAttr propertyName) const;

private:
/// Combined layout spec at the given scope.
Expand Down
6 changes: 3 additions & 3 deletions mlir/include/mlir/Interfaces/DataLayoutInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -468,12 +468,12 @@ def DataLayoutOpInterface : OpInterface<"DataLayoutOpInterface"> {
StaticInterfaceMethod<
/*description=*/"Returns the value of the property, if the property is "
"defined. Otherwise, it returns std::nullopt.",
/*retTy=*/"std::optional<int64_t>",
/*methodName=*/"getDevicePropertyValueAsInt",
/*retTy=*/"std::optional<Attribute>",
/*methodName=*/"getDevicePropertyValue",
/*args=*/(ins "::mlir::DataLayoutEntryInterface":$entry),
/*methodBody=*/"",
/*defaultImplementation=*/[{
return ::mlir::detail::getDevicePropertyValueAsInt(entry);
return ::mlir::detail::getDevicePropertyValue(entry);
}]
>
];
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Dialect/DLTI/DLTI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ TargetDeviceSpecAttr::verify(function_ref<InFlightDiagnostic()> emitError,
<< "dlti.target_device_spec does not allow type as a key: "
<< type;
} else {
// Check that keys in a target device spec are unique.
auto id = entry.getKey().get<StringAttr>();
if (!ids.insert(id).second)
return emitError() << "repeated layout entry key: " << id.getValue();
Expand Down
13 changes: 6 additions & 7 deletions mlir/lib/Interfaces/DataLayoutInterfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,13 +293,12 @@ mlir::detail::getDefaultStackAlignment(DataLayoutEntryInterface entry) {
return value.getValue().getZExtValue();
}

std::optional<int64_t>
mlir::detail::getDevicePropertyValueAsInt(DataLayoutEntryInterface entry) {
std::optional<Attribute>
mlir::detail::getDevicePropertyValue(DataLayoutEntryInterface entry) {
if (entry == DataLayoutEntryInterface())
return std::nullopt;

auto value = cast<IntegerAttr>(entry.getValue());
return value.getValue().getZExtValue();
return entry.getValue();
}

DataLayoutEntryList
Expand Down Expand Up @@ -661,7 +660,7 @@ uint64_t mlir::DataLayout::getStackAlignment() const {
return *stackAlignment;
}

std::optional<int64_t> mlir::DataLayout::getDevicePropertyValueAsInt(
std::optional<Attribute> mlir::DataLayout::getDevicePropertyValue(
TargetSystemSpecInterface::DeviceID deviceID,
StringAttr propertyName) const {
checkValid();
Expand All @@ -676,9 +675,9 @@ std::optional<int64_t> mlir::DataLayout::getDevicePropertyValueAsInt(
// missing, we return std::nullopt so that the users can resort to
// the default value however they want.
if (auto iface = dyn_cast_or_null<DataLayoutOpInterface>(scope))
return iface.getDevicePropertyValueAsInt(entry);
return iface.getDevicePropertyValue(entry);
else
return detail::getDevicePropertyValueAsInt(entry);
return detail::getDevicePropertyValue(entry);
}

//===----------------------------------------------------------------------===//
Expand Down
2 changes: 1 addition & 1 deletion mlir/test/Dialect/DLTI/invalid.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ module attributes {
// expected-error@+2 {{failed to parse DLTI_TargetSystemSpecAttr parameter 'entries' which is to be a `::llvm::ArrayRef<DeviceIDTargetDeviceSpecPair>`}}
dlti.target_system_spec = #dlti.target_system_spec<
0: #dlti.target_device_spec<
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096: i32>>
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096 : i32>>
>} {}

// -----
Expand Down
4 changes: 2 additions & 2 deletions mlir/test/Dialect/DLTI/roundtrip.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
module attributes {
dlti.target_system_spec = #dlti.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"dlti.L1_cache_size_in_bytes", 4096: ui32>>,
#dlti.dl_entry<"dlti.L1_cache_size_in_bytes", 4096 : ui32>>,
"GPU": #dlti.target_device_spec<
#dlti.dl_entry<"dlti.max_vector_op_width", 128: ui32>>
#dlti.dl_entry<"dlti.max_vector_op_width", 128 : ui32>>
>} {}

64 changes: 52 additions & 12 deletions mlir/test/Dialect/DLTI/valid.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
module attributes {
dlti.target_system_spec = #dlti.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096: i32>>,
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096 : i32>>,
"GPU": #dlti.target_device_spec<
#dlti.dl_entry<"max_vector_op_width", 128: i32>>
#dlti.dl_entry<"max_vector_op_width", 128 : i32>>
>} {}

// -----
Expand All @@ -31,9 +31,9 @@ module attributes {
module attributes {
dlti.target_system_spec = #dlti.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096: i32>>,
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096 : i32>>,
"GPU": #dlti.target_device_spec<
#dlti.dl_entry<"L1_cache_size_in_bytes", 8192: i32>>
#dlti.dl_entry<"L1_cache_size_in_bytes", 8192 : i32>>
>} {}

// -----
Expand All @@ -49,9 +49,9 @@ module attributes {
module attributes {
dlti.target_system_spec = #dlti.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096: i64>>,
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096 : i64>>,
"GPU": #dlti.target_device_spec<
#dlti.dl_entry<"L1_cache_size_in_bytes", 8192: i64>>
#dlti.dl_entry<"L1_cache_size_in_bytes", 8192 : i64>>
>} {}

// -----
Expand All @@ -67,9 +67,9 @@ module attributes {
module attributes {
dlti.target_system_spec = #dlti.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"max_vector_op_width", 64: i32>>,
#dlti.dl_entry<"max_vector_op_width", 64 : i32>>,
"GPU": #dlti.target_device_spec<
#dlti.dl_entry<"max_vector_op_width", 128: i32>>
#dlti.dl_entry<"max_vector_op_width", 128 : i32>>
>} {}

// -----
Expand All @@ -85,9 +85,9 @@ module attributes {
module attributes {
dlti.target_system_spec = #dlti.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"max_vector_op_width", 64: i64>>,
#dlti.dl_entry<"max_vector_op_width", 64 : i64>>,
"GPU": #dlti.target_device_spec<
#dlti.dl_entry<"max_vector_op_width", 128: i64>>
#dlti.dl_entry<"max_vector_op_width", 128 : i64>>
>} {}

// -----
Expand All @@ -103,7 +103,47 @@ module attributes {
module attributes {
dlti.target_system_spec = #dlti.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"max_vector_op_width", 64>>,
#dlti.dl_entry<"max_vector_op_width", 64 : i64>>,
"GPU": #dlti.target_device_spec<
#dlti.dl_entry<"max_vector_op_width", 128>>
#dlti.dl_entry<"max_vector_op_width", 128 : i64>>
>} {}

// -----

// Check values of mixed type
//
// CHECK: module attributes {
// CHECK-SAME: dlti.target_system_spec = #dlti.target_system_spec<
// CHECK-SAME: "CPU" : #dlti.target_device_spec<
// CHECK-SAME: #dlti.dl_entry<"L1_cache_size_in_bytes", 4096 : ui32>>,
// CHECK-SAME: "GPU" : #dlti.target_device_spec<
// CHECK-SAME: #dlti.dl_entry<"max_vector_op_width", "128">>
// CHECK-SAME: >} {
// CHECK: }
module attributes {
dlti.target_system_spec = #dlti.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096 : ui32>>,
"GPU": #dlti.target_device_spec<
#dlti.dl_entry<"max_vector_op_width", "128">>
>} {}

// -----

// Check values of mixed type
//
// CHECK: module attributes {
// CHECK-SAME: dlti.target_system_spec = #dlti.target_system_spec<
// CHECK-SAME: "CPU" : #dlti.target_device_spec<
// CHECK-SAME: #dlti.dl_entry<"max_vector_op_width", 4.096000e+03 : f32>>,
// CHECK-SAME: "GPU" : #dlti.target_device_spec<
// CHECK-SAME: #dlti.dl_entry<"L1_cache_size_in_bytes", "128">>
// CHECK-SAME: >} {
// CHECK: }
module attributes {
dlti.target_system_spec = #dlti.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"max_vector_op_width", 4096.0 : f32>>,
"GPU": #dlti.target_device_spec<
#dlti.dl_entry<"L1_cache_size_in_bytes", "128">>
>} {}
20 changes: 10 additions & 10 deletions mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,11 +495,11 @@ TEST(DataLayout, NullSpec) {
EXPECT_EQ(layout.getGlobalMemorySpace(), Attribute());
EXPECT_EQ(layout.getStackAlignment(), 0u);

EXPECT_EQ(layout.getDevicePropertyValueAsInt(
EXPECT_EQ(layout.getDevicePropertyValue(
Builder(&ctx).getStringAttr("CPU" /* device ID*/),
Builder(&ctx).getStringAttr("L1_cache_size_in_bytes")),
std::nullopt);
EXPECT_EQ(layout.getDevicePropertyValueAsInt(
EXPECT_EQ(layout.getDevicePropertyValue(
Builder(&ctx).getStringAttr("CPU" /* device ID*/),
Builder(&ctx).getStringAttr("max_vector_width")),
std::nullopt);
Expand Down Expand Up @@ -535,11 +535,11 @@ TEST(DataLayout, EmptySpec) {
EXPECT_EQ(layout.getGlobalMemorySpace(), Attribute());
EXPECT_EQ(layout.getStackAlignment(), 0u);

EXPECT_EQ(layout.getDevicePropertyValueAsInt(
EXPECT_EQ(layout.getDevicePropertyValue(
Builder(&ctx).getStringAttr("CPU" /* device ID*/),
Builder(&ctx).getStringAttr("L1_cache_size_in_bytes")),
std::nullopt);
EXPECT_EQ(layout.getDevicePropertyValueAsInt(
EXPECT_EQ(layout.getDevicePropertyValue(
Builder(&ctx).getStringAttr("CPU" /* device ID*/),
Builder(&ctx).getStringAttr("max_vector_width")),
std::nullopt);
Expand Down Expand Up @@ -599,8 +599,8 @@ TEST(DataLayout, SpecWithTargetSystemDescEntries) {
module attributes { dl_target_sys_desc_test.target_system_spec =
#dl_target_sys_desc_test.target_system_spec<
"CPU": #dlti.target_device_spec<
#dlti.dl_entry<"L1_cache_size_in_bytes", 4096 : ui32>,
#dlti.dl_entry<"max_vector_op_width", 128 : ui32>>
#dlti.dl_entry<"L1_cache_size_in_bytes", "4096">,
#dlti.dl_entry<"max_vector_op_width", "128">>
> } {}
)MLIR";

Expand All @@ -610,14 +610,14 @@ TEST(DataLayout, SpecWithTargetSystemDescEntries) {

OwningOpRef<ModuleOp> module = parseSourceString<ModuleOp>(ir, &ctx);
DataLayout layout(*module);
EXPECT_EQ(layout.getDevicePropertyValueAsInt(
EXPECT_EQ(layout.getDevicePropertyValue(
Builder(&ctx).getStringAttr("CPU") /* device ID*/,
Builder(&ctx).getStringAttr("L1_cache_size_in_bytes")),
std::optional<int64_t>(4096));
EXPECT_EQ(layout.getDevicePropertyValueAsInt(
std::optional<Attribute>(Builder(&ctx).getStringAttr("4096")));
EXPECT_EQ(layout.getDevicePropertyValue(
Builder(&ctx).getStringAttr("CPU") /* device ID*/,
Builder(&ctx).getStringAttr("max_vector_op_width")),
std::optional<int64_t>(128));
std::optional<Attribute>(Builder(&ctx).getStringAttr("128")));
}

TEST(DataLayout, Caching) {
Expand Down

0 comments on commit 849cea9

Please sign in to comment.