================
@@ -5672,6 +5672,65 @@ def CIR_VecSplatOp : CIR_Op<"vec.splat", [
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// OffloadKind
+//===----------------------------------------------------------------------===//
+
+def CIR_OffloadKind : CIR_I32EnumAttr<"OffloadKind", "offload kind", [
+  I32EnumAttrCase<"Host", 0, "host">,
+  I32EnumAttrCase<"Device", 1, "device">
+]> {
+  let genSpecializedAttr = 0;
+}
+
+def CIR_OffloadKindAttr : CIR_EnumAttr<CIR_OffloadKind, "offload_kind"> {
+  let summary = "Offload kind (host or device)";
+}
+
+//===----------------------------------------------------------------------===//
+// OffloadContainerOp
+//===----------------------------------------------------------------------===//
+
+def CIR_OffloadContainerOp : CIR_Op<"offload.container", [
+    NoRegionArguments, NoTerminator, SingleBlock, SymbolTable]> {
+  let summary = "Container for host and device CIR modules";
+  let description = [{
+    `cir.offload.container` groups one host CIR module with one or more device
+    CIR modules for offload-aware analysis and transformation.
+
+    The body holds nested `builtin.module` operations. The first nested
+    module is the host module and must carry
+    `cir.offload.kind = #cir.offload_kind<host>`. All remaining nested
+    modules are device modules and must carry
+    `cir.offload.kind = #cir.offload_kind<device>`. There must be at least
+    one device module.
+
+    Example:
+
+    ```mlir
+    cir.offload.container {
+      builtin.module @host attributes {cir.offload.kind = 
#cir.offload_kind<host>} {
----------------
RiverDave wrote:

I see what you're getting at.

 The reason we intended this initially to be an op is that we could express the 
invariants we expected in the hierarchy (1 host module, 1 or more device 
modules) explicitly via MLIR's verifier. 

What I understand from your suggestion is that, instead of this being its own 
op, an offload container would be a unit marker attached to a module. Instead 
of this new attribute having its own verifier, we could express its 
relationship with moduleOp with something like: 
CIRDialect::verifyOperationAttribute (I looked at how other dialects do this. 
For reference this is how the gpu dialect verifies that modules containing 
`gpu.module` carry the `gpu.container_module` attribute: 
https://github.com/llvm/llvm-project/blob/e364a21086c71a68cac28f25469a7b014d1c2abd/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp#L428).

With this in mind, there wouldn't be a new op introduced, so a unified module 
could look something like this:

```mlir
module attributes {cir.offload.container} {
  module @host attributes {cir.offload.kind = #cir.offload_kind<host>, ...} { 
... }
  module @sm_90 attributes {cir.offload.kind = #cir.offload_kind<device>, 
cir.offload.bundle_id = "..."} { ... }
  module @gfx942 attributes {cir.offload.kind = #cir.offload_kind<device>, ...} 
{ ... }
}

```

https://github.com/llvm/llvm-project/pull/206576
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to