Skip to content

Commit

Permalink
[mlir] Remove OpaqueElementsAttr
Browse files Browse the repository at this point in the history
This attribute is technical debt from the early stages of MLIR, before
ElementsAttr was an interface and when it was more difficult for
dialects to define their own types of attributes. At present it isn't
used at all in tree (aside from being convenient for eliding other
ElementsAttr), and has had little to no evolution in the past three years.

Differential Revision: https://reviews.llvm.org/D129917
  • Loading branch information
River707 committed Aug 1, 2022
1 parent 7651522 commit 40abd7e
Show file tree
Hide file tree
Showing 17 changed files with 9 additions and 238 deletions.
9 changes: 0 additions & 9 deletions mlir/include/mlir-c/BuiltinAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,15 +455,6 @@ mlirDenseElementsAttrGetStringValue(MlirAttribute attr, intptr_t pos);
MLIR_CAPI_EXPORTED const void *
mlirDenseElementsAttrGetRawData(MlirAttribute attr);

//===----------------------------------------------------------------------===//
// Opaque elements attribute.
//===----------------------------------------------------------------------===//

// TODO: expose Dialect to the bindings and implement accessors here.

/// Checks whether the given attribute is an opaque elements attribute.
MLIR_CAPI_EXPORTED bool mlirAttributeIsAOpaqueElements(MlirAttribute attr);

//===----------------------------------------------------------------------===//
// Sparse elements attribute.
//===----------------------------------------------------------------------===//
Expand Down
62 changes: 0 additions & 62 deletions mlir/include/mlir/IR/BuiltinAttributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -801,68 +801,6 @@ def Builtin_OpaqueAttr : Builtin_Attr<"Opaque", [TypedAttrInterface]> {
let skipDefaultBuilders = 1;
}

//===----------------------------------------------------------------------===//
// OpaqueElementsAttr
//===----------------------------------------------------------------------===//

def Builtin_OpaqueElementsAttr : Builtin_Attr<
"OpaqueElements", [ElementsAttrInterface, TypedAttrInterface]
> {
let summary = "An opaque representation of a multi-dimensional array";
let description = [{
Syntax:

```
opaque-elements-attribute ::= `opaque` `<` dialect-namespace `,`
hex-string-literal `>` `:`
( tensor-type | vector-type )
```

An opaque elements attribute is an elements attribute where the content of
the value is opaque. The representation of the constant stored by this
elements attribute is only understood, and thus decodable, by the dialect
that created it.

Note: The parsed string literal must be in hexadecimal form.

Examples:

```mlir
opaque<"foo_dialect", "0xDEADBEEF"> : tensor<10xi32>
```
}];

// TODO: Provide a way to avoid copying content of large opaque
// tensors This will likely require a new reference attribute kind.
let parameters = (ins "StringAttr":$dialect,
StringRefParameter<"">:$value,
AttributeSelfTypeParameter<"", "ShapedType">:$type);
let builders = [
AttrBuilderWithInferredContext<(ins "StringAttr":$dialect,
"ShapedType":$type,
"StringRef":$value), [{
return $_get(dialect.getContext(), dialect, value, type);
}]>,
AttrBuilderWithInferredContext<(ins "Dialect *":$dialect,
"ShapedType":$type,
"StringRef":$value), [{
MLIRContext *ctxt = dialect->getContext();
StringAttr dialectName = StringAttr::get(ctxt, dialect->getNamespace());
return $_get(ctxt, dialectName, value, type);
}]>
];
let extraClassDeclaration = [{
using ValueType = StringRef;

/// Decodes the attribute value using dialect-specific decoding hook.
/// Returns false if decoding is successful. If not, returns true and leaves
/// 'result' argument unspecified.
bool decode(ElementsAttr &result);
}];
let genVerifyDecl = 1;
let skipDefaultBuilders = 1;
}

//===----------------------------------------------------------------------===//
// SparseElementsAttr
//===----------------------------------------------------------------------===//
Expand Down
37 changes: 0 additions & 37 deletions mlir/include/mlir/Interfaces/DecodeAttributesInterfaces.h

This file was deleted.

38 changes: 0 additions & 38 deletions mlir/lib/AsmParser/AttributeParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ using namespace mlir::detail;
/// (tensor-type | vector-type)
/// | `sparse` `<` attribute-value `,` attribute-value `>`
/// `:` (tensor-type | vector-type)
/// | `opaque` `<` dialect-namespace `,` hex-string-literal
/// `>` `:` (tensor-type | vector-type)
/// | extended-attribute
///
Attribute Parser::parseAttribute(Type type) {
Expand Down Expand Up @@ -143,10 +141,6 @@ Attribute Parser::parseAttribute(Type type) {
return locAttr;
}

// Parse an opaque elements attribute.
case Token::kw_opaque:
return parseOpaqueElementsAttr(type);

// Parse a sparse elements attribute.
case Token::kw_sparse:
return parseSparseElementsAttr(type);
Expand Down Expand Up @@ -249,7 +243,6 @@ OptionalParseResult Parser::parseOptionalAttribute(Attribute &attribute,
case Token::kw_dense_resource:
case Token::kw_false:
case Token::kw_loc:
case Token::kw_opaque:
case Token::kw_sparse:
case Token::kw_true:
case Token::kw_unit:
Expand Down Expand Up @@ -967,37 +960,6 @@ Attribute Parser::parseDenseResourceElementsAttr(Type attrType) {
return DenseResourceElementsAttr::get(shapedType, *handle);
}

/// Parse an opaque elements attribute.
Attribute Parser::parseOpaqueElementsAttr(Type attrType) {
SMLoc loc = getToken().getLoc();
consumeToken(Token::kw_opaque);
if (parseToken(Token::less, "expected '<' after 'opaque'"))
return nullptr;

if (getToken().isNot(Token::string))
return (emitError("expected dialect namespace"), nullptr);

std::string name = getToken().getStringValue();
consumeToken(Token::string);

if (parseToken(Token::comma, "expected ','"))
return nullptr;

Token hexTok = getToken();
if (parseToken(Token::string, "elements hex string should start with '0x'") ||
parseToken(Token::greater, "expected '>'"))
return nullptr;
auto type = parseElementsLiteralType(attrType);
if (!type)
return nullptr;

std::string data;
if (parseElementAttrHexValues(*this, hexTok, data))
return nullptr;
return getChecked<OpaqueElementsAttr>(loc, builder.getStringAttr(name), type,
data);
}

/// Shaped type for elements attribute.
///
/// elements-literal-type ::= vector-type | ranked-tensor-type
Expand Down
3 changes: 0 additions & 3 deletions mlir/lib/AsmParser/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,6 @@ class Parser {
/// or a float attribute.
Attribute parseDecOrHexAttr(Type type, bool isNegative);

/// Parse an opaque elements attribute.
Attribute parseOpaqueElementsAttr(Type attrType);

/// Parse a dense elements attribute.
Attribute parseDenseElementsAttr(Type attrType);
ShapedType parseElementsLiteralType(Type type);
Expand Down
1 change: 0 additions & 1 deletion mlir/lib/AsmParser/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ TOK_KEYWORD(min)
TOK_KEYWORD(mod)
TOK_KEYWORD(none)
TOK_KEYWORD(offset)
TOK_KEYWORD(opaque)
TOK_KEYWORD(size)
TOK_KEYWORD(sparse)
TOK_KEYWORD(step)
Expand Down
8 changes: 0 additions & 8 deletions mlir/lib/CAPI/IR/BuiltinAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,14 +598,6 @@ const void *mlirDenseElementsAttrGetRawData(MlirAttribute attr) {
unwrap(attr).cast<DenseElementsAttr>().getRawData().data());
}

//===----------------------------------------------------------------------===//
// Opaque elements attribute.
//===----------------------------------------------------------------------===//

bool mlirAttributeIsAOpaqueElements(MlirAttribute attr) {
return unwrap(attr).isa<OpaqueElementsAttr>();
}

//===----------------------------------------------------------------------===//
// Sparse elements attribute.
//===----------------------------------------------------------------------===//
Expand Down
19 changes: 3 additions & 16 deletions mlir/lib/IR/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1724,14 +1724,10 @@ static void printSymbolReference(StringRef symbolRef, raw_ostream &os) {
// Print out a valid ElementsAttr that is succinct and can represent any
// potential shape/type, for use when eliding a large ElementsAttr.
//
// We choose to use an opaque ElementsAttr literal with conspicuous content to
// hopefully alert readers to the fact that this has been elided.
//
// Unfortunately, neither of the strings of an opaque ElementsAttr literal will
// accept the string "elided". The first string must be a registered dialect
// name and the latter must be a hex constant.
// We choose to use a dense resource ElementsAttr literal with conspicuous
// content to hopefully alert readers to the fact that this has been elided.
static void printElidedElementsAttr(raw_ostream &os) {
os << R"(opaque<"elided_large_const", "0xDEADBEEF">)";
os << R"(dense_resource<__elided__>)";
}

LogicalResult AsmPrinter::Impl::printAlias(Attribute attr) {
Expand Down Expand Up @@ -1830,15 +1826,6 @@ void AsmPrinter::Impl::printAttribute(Attribute attr,
printSymbolReference(nestedRef.getValue(), os);
}

} else if (auto opaqueAttr = attr.dyn_cast<OpaqueElementsAttr>()) {
if (printerFlags.shouldElideElementsAttr(opaqueAttr)) {
printElidedElementsAttr(os);
} else {
os << "opaque<" << opaqueAttr.getDialect() << ", ";
printHexString(opaqueAttr.getValue());
os << ">";
}

} else if (auto intOrFpEltAttr = attr.dyn_cast<DenseIntOrFPElementsAttr>()) {
if (printerFlags.shouldElideElementsAttr(intOrFpEltAttr)) {
printElidedElementsAttr(os);
Expand Down
24 changes: 0 additions & 24 deletions mlir/lib/IR/BuiltinAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#include "mlir/IR/Operation.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/IR/Types.h"
#include "mlir/Interfaces/DecodeAttributesInterfaces.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/Support/Endian.h"
Expand Down Expand Up @@ -1700,29 +1699,6 @@ template class DenseResourceElementsAttrBase<double>;
} // namespace detail
} // namespace mlir

//===----------------------------------------------------------------------===//
// OpaqueElementsAttr
//===----------------------------------------------------------------------===//

bool OpaqueElementsAttr::decode(ElementsAttr &result) {
Dialect *dialect = getContext()->getLoadedDialect(getDialect());
if (!dialect)
return true;
auto *interface = llvm::dyn_cast<DialectDecodeAttributesInterface>(dialect);
if (!interface)
return true;
return failed(interface->decode(*this, result));
}

LogicalResult
OpaqueElementsAttr::verify(function_ref<InFlightDiagnostic()> emitError,
StringAttr dialect, StringRef value,
ShapedType type) {
if (!Dialect::isValidNamespace(dialect.strref()))
return emitError() << "invalid dialect namespace '" << dialect << "'";
return success();
}

//===----------------------------------------------------------------------===//
// SparseElementsAttr
//===----------------------------------------------------------------------===//
Expand Down
4 changes: 2 additions & 2 deletions mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -713,8 +713,8 @@ class LSPCodeCompleteContext : public AsmParserCodeCompleteContext {
/// Signal a completion for an attribute.
void completeAttribute(const llvm::StringMap<Attribute> &aliases) override {
appendSimpleCompletions({"affine_set", "affine_map", "dense",
"dense_resource", "false", "loc", "opaque",
"sparse", "true", "unit"},
"dense_resource", "false", "loc", "sparse", "true",
"unit"},
lsp::CompletionItemKind::Field,
/*sortText=*/"1");

Expand Down
2 changes: 1 addition & 1 deletion mlir/test/CAPI/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ static void printFirstOfEach(MlirContext ctx, MlirOperation operation) {
mlirOperationPrintWithFlags(operation, flags, printToStderr, NULL);
fprintf(stderr, "\n");
// clang-format off
// CHECK: Op print with all flags: %{{.*}} = "arith.constant"() {elts = opaque<"elided_large_const", "0xDEADBEEF"> : tensor<4xi32>, value = 0 : index} : () -> index loc(unknown)
// CHECK: Op print with all flags: %{{.*}} = "arith.constant"() {elts = dense_resource<__elided__> : tensor<4xi32>, value = 0 : index} : () -> index loc(unknown)
// clang-format on

mlirOpPrintingFlagsDestroy(flags);
Expand Down
6 changes: 0 additions & 6 deletions mlir/test/IR/attribute.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,3 @@ func.func @wrong_shape_fail() {
} : () -> ()
return
}

// -----

// expected-error @+1 {{invalid dialect namespace '"string with space"'}}
#invalid_dialect = opaque<"string with space", "0xDEADBEEF"> : tensor<100xi32>

6 changes: 0 additions & 6 deletions mlir/test/IR/elements-attr-interface.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ arith.constant #test.i64_elements<[10, 11, 12, 13, 14]> : tensor<5xi64>
// expected-error@below {{Test iterating `IntegerAttr`: 10 : i64, 11 : i64, 12 : i64, 13 : i64, 14 : i64}}
arith.constant dense<[10, 11, 12, 13, 14]> : tensor<5xi64>

// expected-error@below {{Test iterating `int64_t`: unable to iterate type}}
// expected-error@below {{Test iterating `uint64_t`: unable to iterate type}}
// expected-error@below {{Test iterating `APInt`: unable to iterate type}}
// expected-error@below {{Test iterating `IntegerAttr`: unable to iterate type}}
arith.constant opaque<"_", "0xDEADBEEF"> : tensor<5xi64>

// Check that we don't crash on empty element attributes.
// expected-error@below {{Test iterating `int64_t`: }}
// expected-error@below {{Test iterating `uint64_t`: }}
Expand Down
18 changes: 0 additions & 18 deletions mlir/test/IR/invalid-builtin-attributes.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,6 @@ func.func @elementsattr_toolarge2() -> () {

// -----

func.func @elementsattr_malformed_opaque() -> () {
"foo"(){bar = opaque<10, "0xQZz123"> : tensor<1xi8>} : () -> () // expected-error {{expected dialect namespace}}
}

// -----

func.func @elementsattr_malformed_opaque1() -> () {
"foo"(){bar = opaque<"_", "0xQZz123"> : tensor<1xi8>} : () -> () // expected-error {{expected string containing hex digits starting with `0x`}}
}

// -----

func.func @elementsattr_malformed_opaque2() -> () {
"foo"(){bar = opaque<"_", "00abc"> : tensor<1xi8>} : () -> () // expected-error {{expected string containing hex digits starting with `0x`}}
}

// -----

func.func @mi() {
// expected-error @+1 {{expected element literal of primitive type}}
"fooi64"(){bar = sparse<vector<1xi64>,[,[,1]
Expand Down
7 changes: 2 additions & 5 deletions mlir/test/IR/pretty-attributes.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@
// tensor which passes don't look at directly, this isn't an issue.
// RUN: mlir-opt %s -mlir-elide-elementsattrs-if-larger=2 | mlir-opt

// CHECK: opaque<"elided_large_const", "0xDEADBEEF"> : tensor<3xi32>
// CHECK: dense_resource<__elided__> : tensor<3xi32>
"test.dense_attr"() {foo.dense_attr = dense<[1, 2, 3]> : tensor<3xi32>} : () -> ()

// CHECK: dense<[1, 2]> : tensor<2xi32>
"test.non_elided_dense_attr"() {foo.dense_attr = dense<[1, 2]> : tensor<2xi32>} : () -> ()

// CHECK: opaque<"elided_large_const", "0xDEADBEEF"> : vector<1x1x10xf16>
// CHECK: dense_resource<__elided__> : vector<1x1x10xf16>
"test.sparse_attr"() {foo.sparse_attr = sparse<[[0, 0, 5]], -2.0> : vector<1x1x10xf16>} : () -> ()

// CHECK: opaque<"elided_large_const", "0xDEADBEEF"> : tensor<100xf32>
"test.opaque_attr"() {foo.opaque_attr = opaque<"elided_large_const", "0xEBFE"> : tensor<100xf32> } : () -> ()

// CHECK: dense<1> : tensor<3xi32>
"test.dense_splat"() {foo.dense_attr = dense<1> : tensor<3xi32>} : () -> ()
2 changes: 1 addition & 1 deletion mlir/test/python/ir/operation.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ def testOperationPrint():
module.operation.print(enable_debug_info=True, use_local_scope=True)

# Test get_asm with options.
# CHECK: value = opaque<"elided_large_const", "0xDEADBEEF"> : tensor<4xi32>
# CHECK: value = dense_resource<__elided__> : tensor<4xi32>
# CHECK: "func.return"(%arg0) : (i32) -> () -:4:7
module.operation.print(
large_elements_limit=2,
Expand Down
1 change: 0 additions & 1 deletion mlir/utils/gdb-scripts/prettyprinters.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ def to_string(self):
'UnitAttr',
'DenseStringElementsAttr',
'DenseIntOrFPElementsAttr',
'OpaqueElementsAttr',
'SparseElementsAttr',
# mlir/IR/BuiltinTypes.h
'ComplexType',
Expand Down

0 comments on commit 40abd7e

Please sign in to comment.