diff --git a/mlir/include/mlir/Dialect/GPU/IR/CompilationAttrs.td b/mlir/include/mlir/Dialect/GPU/IR/CompilationAttrs.td new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/Dialect/GPU/IR/CompilationAttrs.td @@ -0,0 +1,42 @@ +//===-- CompilationAttrs.td - GPU compilation attributes ---*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines GPU compilation related attributes. +// +//===----------------------------------------------------------------------===// + +#ifndef GPU_COMPILATION_ATTRS +#define GPU_COMPILATION_ATTRS + +include "mlir/Dialect/GPU/IR/GPUBase.td" +include "mlir/Dialect/GPU/IR/CompilationAttrInterfaces.td" + +//===----------------------------------------------------------------------===// +// GPU object attribute. +//===----------------------------------------------------------------------===// + +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<#nvvm.target, "..."> + ``` + }]; + let parameters = (ins "TargetAttrInterface":$target, "StringAttr":$object); + let assemblyFormat = [{`<` $target `,` $object `>`}]; +} + +def GPUObjectArrayAttr : + TypedArrayAttrBase; + +#endif // GPU_COMPILATION_ATTRS 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 @@ -16,6 +16,7 @@ include "mlir/Dialect/DLTI/DLTIBase.td" include "mlir/Dialect/GPU/IR/GPUBase.td" include "mlir/Dialect/GPU/IR/CompilationAttrInterfaces.td" +include "mlir/Dialect/GPU/IR/CompilationAttrs.td" include "mlir/Dialect/GPU/IR/ParallelLoopMapperAttr.td" include "mlir/Dialect/GPU/TransformOps/GPUDeviceMappingAttr.td" include "mlir/IR/EnumAttr.td" @@ -1066,6 +1067,46 @@ let assemblyFormat = "attr-dict"; } +def GPU_BinaryOp : GPU_Op<"binary", [Symbol]>, Arguments<(ins + SymbolNameAttr:$sym_name, + OptionalAttr:$offloadingHandler, + 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 optional attribute implementing the offloading LLVM translation interface. + - An array of GPU object attributes. + + During translation into LLVM, the offloading attribute will be called + for translating GPU binary and launch operations into LLVM instructions. If + no attribute is provided, the default handler selects the first object from + the array and embeds it as a string. + + Examples: + ``` + gpu.binary @myobject [#gpu.object<...>, #gpu.object<...>] + gpu.binary @myobject <#foo.my_handler> [#gpu.object<...>, #gpu.object<...>] + ``` + }]; + let builders = [ + OpBuilder<(ins "StringRef":$name, + "OffloadingLLVMTranslationAttrInterface":$offloadingHandler, + "ArrayAttr":$objects)>, + OpBuilder<(ins "StringRef":$name, + "OffloadingLLVMTranslationAttrInterface":$offloadingHandler, + "ArrayRef":$objects)> + ]; + let skipDefaultBuilders = 1; + let assemblyFormat = [{ + $sym_name (`<` $offloadingHandler ^ `>`)? attr-dict $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 @@ -1577,6 +1577,26 @@ targetsAttr = ArrayAttr::get(getContext(), targetsVector); } +//===----------------------------------------------------------------------===// +// GPUBinaryOp +//===----------------------------------------------------------------------===// +void BinaryOp::build(OpBuilder &builder, OperationState &result, StringRef name, + OffloadingLLVMTranslationAttrInterface offloadingHandler, + ArrayAttr objects) { + auto &properties = result.getOrAddProperties(); + result.attributes.push_back(builder.getNamedAttr( + SymbolTable::getSymbolAttrName(), builder.getStringAttr(name))); + properties.objects = objects; + properties.offloadingHandler = offloadingHandler; +} + +void BinaryOp::build(OpBuilder &builder, OperationState &result, StringRef name, + OffloadingLLVMTranslationAttrInterface offloadingHandler, + ArrayRef objects) { + build(builder, result, name, offloadingHandler, + objects.size() > 0 ? builder.getArrayAttr(objects) : ArrayAttr()); +} + //===----------------------------------------------------------------------===// // GPUMemcpyOp //===----------------------------------------------------------------------===// diff --git a/mlir/test/Dialect/GPU/invalid.mlir b/mlir/test/Dialect/GPU/invalid.mlir --- a/mlir/test/Dialect/GPU/invalid.mlir +++ b/mlir/test/Dialect/GPU/invalid.mlir @@ -626,3 +626,17 @@ gpu.module @gpu_funcs [1] { } } + +// ----- + +module { + // expected-error @+1 {{'gpu.binary' op attribute 'objects' failed to satisfy constraint: an array of GPU object attributes with at least 1 elements}} + gpu.binary @binary [] +} + +// ----- + +module { + // expected-error @+1 {{custom op 'gpu.binary' invalid kind of attribute specified}} + gpu.binary @binary <1> [#gpu.object<#nvvm.target, "">] +}