[Mlir-commits] [mlir] 08636d4 - [mlir][spirv] Add Arm.ExperimentalMLOperations.1 extended inst set (#202283)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Jun 9 02:46:28 PDT 2026
Author: Davide Grohmann
Date: 2026-06-09T11:46:23+02:00
New Revision: 08636d456502fb7404e632598e16f3698367a6f7
URL: https://github.com/llvm/llvm-project/commit/08636d456502fb7404e632598e16f3698367a6f7
DIFF: https://github.com/llvm/llvm-project/commit/08636d456502fb7404e632598e16f3698367a6f7.diff
LOG: [mlir][spirv] Add Arm.ExperimentalMLOperations.1 extended inst set (#202283)
This instruction set provides a mechanism to encode experimental ML
operations in SPIR-V modules. Such instructions are encoded via the
single CALL operator in the instruction set by specifying an op_code and
customized inputs values.
Reference:
https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extended/Arm.ExperimentalMLOperations.asciidoc
Signed-off-by: Niklas Lithammer <niklas.lithammer at arm.com>
Signed-off-by: Davide Grohmann <davide.grohmann at arm.com>
Added:
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVExperimentalMLOps.td
mlir/test/Dialect/SPIRV/IR/experimental-ml-ops.mlir
mlir/test/Target/SPIRV/experimental-ml-ops.mlir
Modified:
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.td
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVExperimentalMLOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVExperimentalMLOps.td
new file mode 100644
index 0000000000000..ddd478881958b
--- /dev/null
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVExperimentalMLOps.td
@@ -0,0 +1,52 @@
+//===- SPIRVExperimentalMLOps.td - Experimental ML ops ------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_SPIRV_IR_EXPERIMENTAL_ML_OPS
+#define MLIR_DIALECT_SPIRV_IR_EXPERIMENTAL_ML_OPS
+
+include "mlir/Dialect/SPIRV/IR/SPIRVBase.td"
+
+class SPIRV_ExperimentalMLOp<string mnemonic, int opcode,
+ list<Trait> traits = []> :
+ SPIRV_ExtInstOp<mnemonic, "ExperimentalML", "Arm.ExperimentalMLOperations.1",
+ opcode, traits> {
+ let availability = [
+ MinVersion<SPIRV_V_1_0>,
+ MaxVersion<SPIRV_V_1_6>,
+ Extension<[]>,
+ Capability<[]>
+ ];
+
+ let hasVerifier = 0;
+}
+
+def SPIRV_ExperimentalMLCallOp : SPIRV_ExperimentalMLOp<"Call", 0> {
+ let summary = "Call an Arm experimental ML operation.";
+
+ let description = [{
+ Calls an operation encoded using the Arm.ExperimentalMLOperations extended
+ instruction set. The `opcode` attribute is serialized as the operation
+ opcode literal integer operand of CALL.
+ }];
+
+ let arguments = (ins
+ I32Attr:$opcode,
+ Variadic<AnyType>:$parameters
+ );
+
+ let results = (outs
+ AnyType:$output
+ );
+
+ let assemblyFormat = [{
+ `opcode` `=` $opcode `,`
+ $parameters attr-dict `:` functional-type($parameters, $output)
+ }];
+}
+
+#endif // MLIR_DIALECT_SPIRV_IR_EXPERIMENTAL_ML_OPS
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.td
index 3ef9699154cd1..14dc76aef57db 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.td
@@ -30,6 +30,7 @@ include "mlir/Dialect/SPIRV/IR/SPIRVCastOps.td"
include "mlir/Dialect/SPIRV/IR/SPIRVCompositeOps.td"
include "mlir/Dialect/SPIRV/IR/SPIRVControlFlowOps.td"
include "mlir/Dialect/SPIRV/IR/SPIRVCooperativeMatrixOps.td"
+include "mlir/Dialect/SPIRV/IR/SPIRVExperimentalMLOps.td"
include "mlir/Dialect/SPIRV/IR/SPIRVIntelExtOps.td"
include "mlir/Dialect/SPIRV/IR/SPIRVGLOps.td"
include "mlir/Dialect/SPIRV/IR/SPIRVGraphOps.td"
diff --git a/mlir/test/Dialect/SPIRV/IR/experimental-ml-ops.mlir b/mlir/test/Dialect/SPIRV/IR/experimental-ml-ops.mlir
new file mode 100644
index 0000000000000..caccb043d3af2
--- /dev/null
+++ b/mlir/test/Dialect/SPIRV/IR/experimental-ml-ops.mlir
@@ -0,0 +1,14 @@
+// RUN: mlir-opt %s | FileCheck %s
+
+//===----------------------------------------------------------------------===//
+// spirv.ExperimentalML.Call
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @experimental_ml_call(%arg0: !spirv.arm.tensor<1x16xf32>, %arg1: !spirv.arm.tensor<1x16xf32>) -> !spirv.arm.tensor<1x16xf32> {
+ // CHECK: %[[NAME:.*]] = spirv.Constant dense<[83, 101, 108, 102, 65, 116, 116, 101, 110, 116, 105, 111, 110, 79, 112]> : tensor<15xi8> : !spirv.array<15 x i8>
+ %name = spirv.Constant dense<[83, 101, 108, 102, 65, 116, 116, 101, 110, 116, 105, 111, 110, 79, 112]> : tensor<15xi8> : !spirv.array<15 x i8>
+ // CHECK: {{%.*}} = spirv.ExperimentalML.Call opcode = 0, %[[NAME]], %arg0, %arg1 : (!spirv.array<15 x i8>, !spirv.arm.tensor<1x16xf32>, !spirv.arm.tensor<1x16xf32>) -> !spirv.arm.tensor<1x16xf32>
+ %0 = spirv.ExperimentalML.Call opcode = 0, %name, %arg0, %arg1 : (!spirv.array<15 x i8>, !spirv.arm.tensor<1x16xf32>, !spirv.arm.tensor<1x16xf32>) -> !spirv.arm.tensor<1x16xf32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x16xf32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1x16xf32>
+}
diff --git a/mlir/test/Target/SPIRV/experimental-ml-ops.mlir b/mlir/test/Target/SPIRV/experimental-ml-ops.mlir
new file mode 100644
index 0000000000000..5876f7339c330
--- /dev/null
+++ b/mlir/test/Target/SPIRV/experimental-ml-ops.mlir
@@ -0,0 +1,25 @@
+// RUN: mlir-translate --no-implicit-module --test-spirv-roundtrip %s | FileCheck %s
+// RUN: %if spirv-tools %{ mlir-translate --no-implicit-module --serialize-spirv %s | spirv-val %}
+
+// CHECK: spirv.module Logical Vulkan requires
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ // CHECK: spirv.GlobalVariable @main_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x16xf32>, UniformConstant>
+ spirv.GlobalVariable @main_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x16xf32>, UniformConstant>
+ // CHECK: spirv.GlobalVariable @main_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<1x16xf32>, UniformConstant>
+ spirv.GlobalVariable @main_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<1x16xf32>, UniformConstant>
+ // CHECK: spirv.GlobalVariable @main_res_0 bind(0, 2) : !spirv.ptr<!spirv.arm.tensor<1x16xf32>, UniformConstant>
+ spirv.GlobalVariable @main_res_0 bind(0, 2) : !spirv.ptr<!spirv.arm.tensor<1x16xf32>, UniformConstant>
+ // CHECK: spirv.ARM.GraphEntryPoint @main, @main_arg_0, @main_arg_1, @main_res_0
+ spirv.ARM.GraphEntryPoint @main, @main_arg_0, @main_arg_1, @main_res_0
+ // CHECK: spirv.ARM.Graph @main(%arg0: !spirv.arm.tensor<1x16xf32>, %arg1: !spirv.arm.tensor<1x16xf32>) -> !spirv.arm.tensor<1x16xf32>
+ spirv.ARM.Graph @main(%arg0: !spirv.arm.tensor<1x16xf32>, %arg1: !spirv.arm.tensor<1x16xf32>) -> !spirv.arm.tensor<1x16xf32> {
+ // CHECK: %[[NAME:.*]] = spirv.Constant [83 : i8, 101 : i8, 108 : i8, 102 : i8, 65 : i8, 116 : i8, 116 : i8, 101 : i8, 110 : i8, 116 : i8, 105 : i8, 111 : i8, 110 : i8, 79 : i8, 112 : i8] : !spirv.array<15 x i8>
+ %name = spirv.Constant dense<[83, 101, 108, 102, 65, 116, 116, 101, 110, 116, 105, 111, 110, 79, 112]> : tensor<15xi8> : !spirv.array<15 x i8>
+ // CHECK: %[[ATTRS:.*]] = spirv.Constant [123 : i8, 34 : i8, 111 : i8, 112 : i8, 101 : i8, 114 : i8, 97 : i8, 116 : i8, 111 : i8, 114 : i8, 95 : i8, 110 : i8, 97 : i8, 109 : i8, 101 : i8, 34 : i8, 58 : i8, 34 : i8, 83 : i8, 101 : i8, 108 : i8, 102 : i8, 65 : i8, 116 : i8, 116 : i8, 101 : i8, 110 : i8, 116 : i8, 105 : i8, 111 : i8, 110 : i8, 79 : i8, 112 : i8, 34 : i8, 125 : i8] : !spirv.array<35 x i8>
+ %attrs = spirv.Constant dense<[123, 34, 111, 112, 101, 114, 97, 116, 111, 114, 95, 110, 97, 109, 101, 34, 58, 34, 83, 101, 108, 102, 65, 116, 116, 101, 110, 116, 105, 111, 110, 79, 112, 34, 125]> : tensor<35xi8> : !spirv.array<35 x i8>
+ // CHECK: %[[CALL:.*]] = spirv.ExperimentalML.Call opcode = 0, %[[NAME]], %[[ATTRS]], %arg0, %arg1 : (!spirv.array<15 x i8>, !spirv.array<35 x i8>, !spirv.arm.tensor<1x16xf32>, !spirv.arm.tensor<1x16xf32>) -> !spirv.arm.tensor<1x16xf32>
+ %0 = spirv.ExperimentalML.Call opcode = 0, %name, %attrs, %arg0, %arg1 : (!spirv.array<15 x i8>, !spirv.array<35 x i8>, !spirv.arm.tensor<1x16xf32>, !spirv.arm.tensor<1x16xf32>) -> !spirv.arm.tensor<1x16xf32>
+ // CHECK: spirv.ARM.GraphOutputs %[[CALL]] : !spirv.arm.tensor<1x16xf32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1x16xf32>
+ }
+}
More information about the Mlir-commits
mailing list