[llvm-branch-commits] [mlir] f6c7ebe - [MLIR][SPIRVToLLVM] Updated documentation on entry points and not supported ops

2020-12-21 Thread George Mitenkov via llvm-branch-commits

Author: George Mitenkov
Date: 2020-12-21T11:20:40+03:00
New Revision: f6c7ebe76ac5df175050a558e767a68abee07425

URL: 
https://github.com/llvm/llvm-project/commit/f6c7ebe76ac5df175050a558e767a68abee07425
DIFF: 
https://github.com/llvm/llvm-project/commit/f6c7ebe76ac5df175050a558e767a68abee07425.diff

LOG: [MLIR][SPIRVToLLVM] Updated documentation on entry points and not 
supported ops

This patch addresses two issues:
1. Not supported ops are updated to pick up the changes in the
SPIR-V dialect.

2. Conversion on `spv.ExecutionMode` is updated.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D91881

Added: 


Modified: 
mlir/docs/SPIRVToLLVMDialectConversion.md

Removed: 




diff  --git a/mlir/docs/SPIRVToLLVMDialectConversion.md 
b/mlir/docs/SPIRVToLLVMDialectConversion.md
index c42a529beed1..3aa4d0fa43a1 100644
--- a/mlir/docs/SPIRVToLLVMDialectConversion.md
+++ b/mlir/docs/SPIRVToLLVMDialectConversion.md
@@ -368,18 +368,37 @@ non-vector  | `spv.CompositeInsert`  | 
`llvm.insertvalue`
 
 ### `spv.EntryPoint` and `spv.ExecutionMode`
 
-**Note: these conversions are likely to be changed in the future**
-
 First of all, it is important to note that there is no direct representation of
-entry points in LLVM. At the moment, we choose to **remove these ops**, 
assuming
-that the module generated from SPIR-V has no other internal functions (This
-assumption is actually made in 
[`mlir-spirv-cpu-runner`](#`mlir-spirv-cpu-runner`)).
+entry points in LLVM. At the moment, we use the following approach:
+
+* `spv.EntryPoint` is simply removed.
+
+* In contrast, `spv.ExecutionMode` may contain important information about the
+  entry point. For example, `LocalSize` provides information about the
+  work-group size that can be reused.
 
-However, these ops can be used to see which functions in the module are entry
-point functions. `spv.ExecutionMode` also carries the metadata associated with
-the entry point such as `LocalSize`, which indicates the workgroup size in the
-x, y, and z dimensions. It will be useful to represent this on the LLVM side
-(TODO).
+  In order to preserve this inforamtion, `spv.ExecutionMode` is converted to
+  a struct global variable that stores the execution mode id and any variables
+  associated with it. In C, the struct has the structure shown below.
+
+  ```C
+  // No values are associated  // There are values that are associated
+  // with this entry point.// with this entry point.
+  struct { struct {
+int32_t executionMode; int32_t executionMode;
+  };   int32_t values[];
+   };
+  ```
+
+  ```mlir
+  // spv.ExecutionMode @empty "ContractionOff"
+  llvm.mlir.global external constant @{{.*}}() : !llvm.struct<(i32)> {
+%0   = llvm.mlir.undef : !llvm.struct<(i32)>
+%1   = llvm.mlir.constant(31 : i32) : !llvm.i32
+%ret = llvm.insertvalue %1, %0[0 : i32] : !llvm.struct<(i32)>
+llvm.return %ret : !llvm.struct<(i32)>
+  }
+  ```
 
 ### Logical ops
 
@@ -604,9 +623,10 @@ cover all possible corner cases.
 
 There is no support of the following ops:
 
-*   All Atomic ops
+*   All atomic ops
+*   All group ops
 *   All matrix ops
-*   All GroupNonUniform ops
+*   All OCL ops
 
 As well as:
 
@@ -614,15 +634,20 @@ As well as:
 *   spv.ControlBarrier
 *   spv.CopyMemory
 *   spv.FMod
+*   spv.GLSL.Acos
+*   spv.GLSL.Asin
+*   spv.GLSL.Atan
+*   spv.GLSL.Cosh
+*   spv.GLSL.FSign
 *   spv.GLSL.SAbs
+*   spv.GLSL.Sinh
 *   spv.GLSL.SSign
-*   spv.GLSL.FSign
 *   spv.MemoryBarrier
 *   spv.mlir.referenceof
 *   spv.SMod
 *   spv.specConstant
-*   spv.SubgroupBallotKHR
 *   spv.Unreachable
+*   spv.VectorExtractDynamic
 
 ## Control flow conversion
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] be96137 - [MLIR][SPIRVToLLVM] Updated documentation on spirv-cpu-runner

2020-12-21 Thread George Mitenkov via llvm-branch-commits

Author: George Mitenkov
Date: 2020-12-22T01:47:43+03:00
New Revision: be961374611a4be1b042cce7e6cc4cd12a1b4fd7

URL: 
https://github.com/llvm/llvm-project/commit/be961374611a4be1b042cce7e6cc4cd12a1b4fd7
DIFF: 
https://github.com/llvm/llvm-project/commit/be961374611a4be1b042cce7e6cc4cd12a1b4fd7.diff

LOG: [MLIR][SPIRVToLLVM] Updated documentation on spirv-cpu-runner

This patch adds documentation for the `mlir-spirv-cpu-runner`.
It provides an overview of applied transformations and passes, as
well as an example walk-through.

Some typos in the documentation have been fixed as well.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D93620

Added: 


Modified: 
mlir/docs/SPIRVToLLVMDialectConversion.md

Removed: 




diff  --git a/mlir/docs/SPIRVToLLVMDialectConversion.md 
b/mlir/docs/SPIRVToLLVMDialectConversion.md
index 3aa4d0fa43a1..bdae08c1e230 100644
--- a/mlir/docs/SPIRVToLLVMDialectConversion.md
+++ b/mlir/docs/SPIRVToLLVMDialectConversion.md
@@ -377,7 +377,7 @@ entry points in LLVM. At the moment, we use the following 
approach:
   entry point. For example, `LocalSize` provides information about the
   work-group size that can be reused.
 
-  In order to preserve this inforamtion, `spv.ExecutionMode` is converted to
+  In order to preserve this information, `spv.ExecutionMode` is converted to
   a struct global variable that stores the execution mode id and any variables
   associated with it. In C, the struct has the structure shown below.
 
@@ -816,7 +816,140 @@ to LLVM ops. At the moment, SPIR-V module attributes are 
ignored.
 
 ## `mlir-spirv-cpu-runner`
 
-**Note: this is a section in progress, more information will appear soon**
+`mlir-spirv-cpu-runner` allows to execute `gpu` dialect kernel on the CPU via
+SPIR-V to LLVM dialect conversion. Currently, only single-threaded kernel is
+supported.
+
+To build the runner, add the following option to `cmake`:
+```bash
+-DMLIR_SPIRV_CPU_RUNNER_ENABLED=1
+```
+
+### Pipeline
+
+The `gpu` module with the kernel and the host code undergo the following
+transformations:
+
+*   Convert the `gpu` module into SPIR-V dialect, lower ABI attributes and
+update version, capability and extension.
+
+*   Emulate the kernel call by converting the launching operation into a normal
+function call. The data from the host side to the device is passed via
+copying to global variables. These are created in both the host and the
+kernel code and later linked when nested modules are folded.
+
+*   Convert SPIR-V dialect kernel to LLVM dialect via the new conversion path.
+
+After these passes, the IR transforms into a nested LLVM module - a main module
+representing the host code and a kernel module. These modules are linked and
+executed using `ExecutionEngine`.
+
+### Walk-through
+
+This section gives a detailed overview of the IR changes while running
+`mlir-spirv-cpu-runner`. First, consider that we have the following IR. (For
+simplicity some type annotations and function implementations have been
+omitted).
+
+```mlir
+gpu.module @foo {
+  gpu.func @bar(%arg: memref<8xi32>) {
+// Kernel code.
+gpu.return
+  }
+}
+
+func @main() {
+  // Fill the buffer with some data
+  %buffer = alloc : memref<8xi32>
+  %data = ...
+  call fillBuffer(%buffer, %data)
+
+  "gpu.launch_func"(/*grid dimensions*/, %buffer) {
+kernel = @foo::bar
+  }
+}
+```
+
+Lowering `gpu` dialect to SPIR-V dialect results in
+
+```mlir
+spv.module @__spv__foo /*VCE triple and other metadata here*/ {
+  spv.globalVariable @__spv__foo_arg bind(0,0) : ...
+  spv.func @bar() {
+// Kernel code.
+  }
+  spv.EntryPoint @bar, ...
+}
+
+func @main() {
+  // Fill the buffer with some data.
+  %buffer = alloc : memref<8xi32>
+  %data = ...
+  call fillBuffer(%buffer, %data)
+
+  "gpu.launch_func"(/*grid dimensions*/, %buffer) {
+kernel = @foo::bar
+  }
+}
+```
+
+Then, the lowering from standard dialect to LLVM dialect is applied to the host
+code.
+
+```mlir
+spv.module @__spv__foo /*VCE triple and other metadata here*/ {
+  spv.globalVariable @__spv__foo_arg bind(0,0) : ...
+  spv.func @bar() {
+// Kernel code.
+  }
+  spv.EntryPoint @bar, ...
+}
+
+// Kernel function declaration.
+llvm.func @__spv__foo_bar() : ...
+
+llvm.func @main() {
+  // Fill the buffer with some data.
+  llvm.call fillBuffer(%buffer, %data)
+
+  // Copy data to the global variable, call kernel, and copy the data back.
+  %addr = llvm.mlir.addressof @__spv__foo_arg_descriptor_set0_binding0 : ...
+  "llvm.intr.memcpy"(%addr, %buffer) : ...
+  llvm.call @__spv__foo_bar()
+  "llvm.intr.memcpy"(%buffer, %addr) : ...
+
+  llvm.return
+}
+```
+
+Finally, SPIR-V module is converted to LLVM and the symbol names are resolved
+for the linkage.
+
+```mlir
+module @__spv__foo {
+  llvm.mlir.global @__spv__foo_arg_descriptor_set0_binding0 : ...
+  llvm.func @__spv__foo_bar() {
+// Kernel