diff --git a/mlir/include/mlir/Dialect/GPU/IR/GPUOps.td b/mlir/include/mlir/Dialect/GPU/IR/GPUOps.td --- a/mlir/include/mlir/Dialect/GPU/IR/GPUOps.td +++ b/mlir/include/mlir/Dialect/GPU/IR/GPUOps.td @@ -1064,6 +1064,54 @@ let assemblyFormat = "attr-dict"; } +def GPU_ObjectAttr : GPU_Attr<"Object", "object"> { + let description = [{ + A GPU object attribute pairs a GPU target with a binary string, + encapsulating the information of how the object was generated with the + object itself. + + The target attribute must implement the `TargetAttrInterface` interface. + + ``` + #gpu.object<#gpu.nvptx, "..."> + ``` + }]; + let parameters = (ins "Attribute":$target, "StringAttr":$object); + let assemblyFormat = [{`<` $target `,` $object `>`}]; + let genVerifyDecl = 1; +} + +def GPUObjectArrayAttr : + TypedArrayAttrBase; + +def GPU_BinaryOp : GPU_Op<"binary", [Symbol, GlobalSymbol]>, + Arguments<(ins SymbolNameAttr:$sym_name, + GPUObjectManagerAttr:$objectManager, + ConfinedAttr]>:$objects)> { + let summary = "An op for storing serialized GPU binary objects."; + let description = [{ + GPU binaries provide a semantic mechanism for storing GPU objects, + e.g. the result of compiling a GPU module to an object file. + + This operation has 3 arguments: + - The name of the binary. + - An attribute implementing the `ObjectManagerAttrInterface` interface. + - An array of GPU object attributes. + + ``` + gpu.binary @myobject [#gpu.object<...>, #gpu.object<...>] + ``` + }]; + let builders = [ + OpBuilder<(ins "StringRef":$name, "Attribute":$objectManager, + "ArrayAttr":$objects)> + ]; + let skipDefaultBuilders = 1; + let assemblyFormat = [{ + $sym_name custom($objectManager) attr-dict-with-keyword $objects + }]; +} + def GPU_HostRegisterOp : GPU_Op<"host_register">, Arguments<(ins AnyUnrankedMemRef:$value)> { let summary = "Registers a memref for access from device."; diff --git a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp --- a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp +++ b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp @@ -1530,6 +1530,41 @@ targetsAttr = ArrayAttr::get(getContext(), targetsVector); } +//===----------------------------------------------------------------------===// +// GPUBinaryOp +//===----------------------------------------------------------------------===// + +LogicalResult +ObjectAttr::verify(function_ref emitError, + Attribute target, StringAttr object) { + if (target && target.hasTrait()) + return success(); + emitError() << "The target parameter must implement `TargetAttrInterface`."; + return failure(); +} + +void BinaryOp::build(OpBuilder &builder, OperationState &result, StringRef name, + Attribute manager, ArrayAttr objects) { + auto &properties = result.getOrAddProperties(); + result.attributes.push_back(builder.getNamedAttr( + SymbolTable::getSymbolAttrName(), builder.getStringAttr(name))); + properties.objects = objects; + properties.objectManager = manager; +} + +static ParseResult parseObjectManager(OpAsmParser &parser, + Attribute &objectManager) { + if (parser.parseAttribute(objectManager)) + return failure(); + return success(); +} + +static void printObjectManager(OpAsmPrinter &printer, Operation *op, + Attribute objectManager) { + if (objectManager) + printer << '<' << objectManager << '>'; +} + //===----------------------------------------------------------------------===// // GPUMemcpyOp //===----------------------------------------------------------------------===//