-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[mlir][spirv] Add integration test for vector.interleave
and vector.shuffle
#93595
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-mlir @llvm/pr-subscribers-mlir-gpu Author: Angel Zhang (angelz913) Changes
Full diff: https://github.com/llvm/llvm-project/pull/93595.diff 2 Files Affected:
diff --git a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp
index 1d1db913e3df2..2677d4e24be2c 100644
--- a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp
+++ b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp
@@ -16,6 +16,7 @@
#include "mlir/Conversion/ArithToSPIRV/ArithToSPIRV.h"
#include "mlir/Conversion/FuncToSPIRV/FuncToSPIRV.h"
#include "mlir/Conversion/GPUToSPIRV/GPUToSPIRV.h"
+#include "mlir/Conversion/VectorToSPIRV/VectorToSPIRV.h"
#include "mlir/Conversion/MemRefToSPIRV/MemRefToSPIRV.h"
#include "mlir/Conversion/SCFToSPIRV/SCFToSPIRV.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -132,6 +133,7 @@ void GPUToSPIRVPass::runOnOperation() {
mlir::arith::populateArithToSPIRVPatterns(typeConverter, patterns);
populateMemRefToSPIRVPatterns(typeConverter, patterns);
populateFuncToSPIRVPatterns(typeConverter, patterns);
+ populateVectorToSPIRVPatterns(typeConverter, patterns);
if (failed(applyFullConversion(gpuModule, *target, std::move(patterns))))
return signalPassFailure();
diff --git a/mlir/test/mlir-vulkan-runner/vector-interleave.mlir b/mlir/test/mlir-vulkan-runner/vector-interleave.mlir
new file mode 100644
index 0000000000000..d760c1631c473
--- /dev/null
+++ b/mlir/test/mlir-vulkan-runner/vector-interleave.mlir
@@ -0,0 +1,53 @@
+// RUN: mlir-vulkan-runner %s \
+// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
+// RUN: --entry-point-result=void | FileCheck %s
+
+// CHECK: [0, 2, 1, 3]
+module attributes {
+ gpu.container_module,
+ spirv.target_env = #spirv.target_env<
+ #spirv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, #spirv.resource_limits<>>
+} {
+ gpu.module @kernels {
+ gpu.func @kernel_vector_interleave(%arg0 : memref<2xi32>, %arg1 : memref<2xi32>, %arg2 : memref<4xi32>)
+ kernel attributes { spirv.entry_point_abi = #spirv.entry_point_abi<workgroup_size = [1, 1, 1]>} {
+ %c0 = arith.constant 0 : index
+ %vec0 = vector.load %arg0[%c0] : memref<2xi32>, vector<2xi32>
+ %vec1 = vector.load %arg1[%c0] : memref<2xi32>, vector<2xi32>
+ %result = vector.interleave %vec0, %vec1 : vector<2xi32> -> vector<4xi32>
+ vector.store %result, %arg2[%c0] : memref<4xi32>, vector<4xi32>
+ gpu.return
+ }
+ }
+
+ func.func @main() {
+ // Allocate 3 buffers.
+ %buf0 = memref.alloc() : memref<2xi32>
+ %buf1 = memref.alloc() : memref<2xi32>
+ %buf2 = memref.alloc() : memref<4xi32>
+
+ %idx0 = arith.constant 0 : index
+ %idx1 = arith.constant 1 : index
+ %idx4 = arith.constant 4 : index
+
+ // Initialize input buffer
+ %buf0_vals = arith.constant dense<[0, 1]> : vector<2xi32>
+ %buf1_vals = arith.constant dense<[2, 3]> : vector<2xi32>
+ vector.store %buf0_vals, %buf0[%idx0] : memref<2xi32>, vector<2xi32>
+ vector.store %buf1_vals, %buf1[%idx0] : memref<2xi32>, vector<2xi32>
+
+ // Initialize output buffer.
+ %value0 = arith.constant 0 : i32
+ %buf3 = memref.cast %buf2 : memref<4xi32> to memref<?xi32>
+ call @fillResource1DInt(%buf3, %value0) : (memref<?xi32>, i32) -> ()
+
+ gpu.launch_func @kernels::@kernel_vector_interleave
+ blocks in (%idx4, %idx1, %idx1) threads in (%idx1, %idx1, %idx1)
+ args(%buf0 : memref<2xi32>, %buf1 : memref<2xi32>, %buf2 : memref<4xi32>)
+ %buf4 = memref.cast %buf3 : memref<?xi32> to memref<*xi32>
+ call @printMemrefI32(%buf4) : (memref<*xi32>) -> ()
+ return
+ }
+ func.func private @fillResource1DInt(%0 : memref<?xi32>, %1 : i32)
+ func.func private @printMemrefI32(%ptr : memref<*xi32>)
+}
|
@llvm/pr-subscribers-mlir-spirv Author: Angel Zhang (angelz913) Changes
Full diff: https://github.com/llvm/llvm-project/pull/93595.diff 2 Files Affected:
diff --git a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp
index 1d1db913e3df2..2677d4e24be2c 100644
--- a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp
+++ b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp
@@ -16,6 +16,7 @@
#include "mlir/Conversion/ArithToSPIRV/ArithToSPIRV.h"
#include "mlir/Conversion/FuncToSPIRV/FuncToSPIRV.h"
#include "mlir/Conversion/GPUToSPIRV/GPUToSPIRV.h"
+#include "mlir/Conversion/VectorToSPIRV/VectorToSPIRV.h"
#include "mlir/Conversion/MemRefToSPIRV/MemRefToSPIRV.h"
#include "mlir/Conversion/SCFToSPIRV/SCFToSPIRV.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
@@ -132,6 +133,7 @@ void GPUToSPIRVPass::runOnOperation() {
mlir::arith::populateArithToSPIRVPatterns(typeConverter, patterns);
populateMemRefToSPIRVPatterns(typeConverter, patterns);
populateFuncToSPIRVPatterns(typeConverter, patterns);
+ populateVectorToSPIRVPatterns(typeConverter, patterns);
if (failed(applyFullConversion(gpuModule, *target, std::move(patterns))))
return signalPassFailure();
diff --git a/mlir/test/mlir-vulkan-runner/vector-interleave.mlir b/mlir/test/mlir-vulkan-runner/vector-interleave.mlir
new file mode 100644
index 0000000000000..d760c1631c473
--- /dev/null
+++ b/mlir/test/mlir-vulkan-runner/vector-interleave.mlir
@@ -0,0 +1,53 @@
+// RUN: mlir-vulkan-runner %s \
+// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
+// RUN: --entry-point-result=void | FileCheck %s
+
+// CHECK: [0, 2, 1, 3]
+module attributes {
+ gpu.container_module,
+ spirv.target_env = #spirv.target_env<
+ #spirv.vce<v1.0, [Shader], [SPV_KHR_storage_buffer_storage_class]>, #spirv.resource_limits<>>
+} {
+ gpu.module @kernels {
+ gpu.func @kernel_vector_interleave(%arg0 : memref<2xi32>, %arg1 : memref<2xi32>, %arg2 : memref<4xi32>)
+ kernel attributes { spirv.entry_point_abi = #spirv.entry_point_abi<workgroup_size = [1, 1, 1]>} {
+ %c0 = arith.constant 0 : index
+ %vec0 = vector.load %arg0[%c0] : memref<2xi32>, vector<2xi32>
+ %vec1 = vector.load %arg1[%c0] : memref<2xi32>, vector<2xi32>
+ %result = vector.interleave %vec0, %vec1 : vector<2xi32> -> vector<4xi32>
+ vector.store %result, %arg2[%c0] : memref<4xi32>, vector<4xi32>
+ gpu.return
+ }
+ }
+
+ func.func @main() {
+ // Allocate 3 buffers.
+ %buf0 = memref.alloc() : memref<2xi32>
+ %buf1 = memref.alloc() : memref<2xi32>
+ %buf2 = memref.alloc() : memref<4xi32>
+
+ %idx0 = arith.constant 0 : index
+ %idx1 = arith.constant 1 : index
+ %idx4 = arith.constant 4 : index
+
+ // Initialize input buffer
+ %buf0_vals = arith.constant dense<[0, 1]> : vector<2xi32>
+ %buf1_vals = arith.constant dense<[2, 3]> : vector<2xi32>
+ vector.store %buf0_vals, %buf0[%idx0] : memref<2xi32>, vector<2xi32>
+ vector.store %buf1_vals, %buf1[%idx0] : memref<2xi32>, vector<2xi32>
+
+ // Initialize output buffer.
+ %value0 = arith.constant 0 : i32
+ %buf3 = memref.cast %buf2 : memref<4xi32> to memref<?xi32>
+ call @fillResource1DInt(%buf3, %value0) : (memref<?xi32>, i32) -> ()
+
+ gpu.launch_func @kernels::@kernel_vector_interleave
+ blocks in (%idx4, %idx1, %idx1) threads in (%idx1, %idx1, %idx1)
+ args(%buf0 : memref<2xi32>, %buf1 : memref<2xi32>, %buf2 : memref<4xi32>)
+ %buf4 = memref.cast %buf3 : memref<?xi32> to memref<*xi32>
+ call @printMemrefI32(%buf4) : (memref<*xi32>) -> ()
+ return
+ }
+ func.func private @fillResource1DInt(%0 : memref<?xi32>, %1 : i32)
+ func.func private @printMemrefI32(%ptr : memref<*xi32>)
+}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
263ede9
to
11cea8b
Compare
vector.interleave
vector.interleave
and vector.shuffle
vector.interleave
and vector.shuffle
vector.interleave
and vector.shuffle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks fine. Just need to format the code and confirm the dependencies.
Co-authored-by: Jakub Kuderski <[email protected]>
@angelz913 please format the code and this should be good to land |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This broke the gcc-7 bot unfortunately, I reverted in #93732 |
Actually this crashed with clang as well: https://lab.llvm.org/buildbot/#/builders/61 |
Thanks, @joker-eph |
This is most likely caused by the nvidia driver rejecting the spir-v blob, whereas amdvlk/swiftshader seem more forgiving: https://gist.github.com/kuhar/f65f36d01e8c0b6018e2344ccbf39646 |
…or.shuffle` (#93858) This PR tries to reland #93595 which was reverted in #93732 due to some issues. The original PR: - Add integration test for `vector.shuffle` and `vector.interleave` - Add `VectorToSPIRV` patterns to `GPUToSPIRVPass` Description of the issue: - #93595 (comment) - Using either `vector.load` or `vector.store` in the kernel function will cause the validation layer to report an error - Trying to bypass the issue by using `memref.load` and `memref.store` to load/store individual elements from/to the vectors, and populate the vectors using `vector.insertelement` and `vector.extractelement` instead.
vector.shuffle
andvector.interleave
, mentioned in issue [mlir][spirv] Add integration tests forvector.shuffle
/vector.interleave
#91978VectorToSPIRV
patterns toGPUToSPIRVPass