Drop lists of VulkanSPIRV flags. (#16680)
Previously this could take a list of `--iree-vulkan-target-triple` and
`--iree-vulkan-target-env` flags. Other backends only support a single
flag and as we move towards multi-device, we will be standardizing on
device spec files with `#hal.device.target`s and their executable
formats, _not_ loose flags for each backend.
Now only one of those flags can be set at a time and both are a single
value, not a list.
Progress on https://github.com/openxla/iree/issues/15468 (the flag
parsing code in here was not compatible with how compiler plugins are
currently configured).
diff --git a/compiler/src/iree/compiler/Dialect/HAL/Target/VulkanSPIRV/VulkanSPIRVTarget.cpp b/compiler/src/iree/compiler/Dialect/HAL/Target/VulkanSPIRV/VulkanSPIRVTarget.cpp
index 11aff8e..015a8b3 100644
--- a/compiler/src/iree/compiler/Dialect/HAL/Target/VulkanSPIRV/VulkanSPIRVTarget.cpp
+++ b/compiler/src/iree/compiler/Dialect/HAL/Target/VulkanSPIRV/VulkanSPIRVTarget.cpp
@@ -37,17 +37,15 @@
// llvm::cl::OptionCategory halVulkanSPIRVOptionsCategory(
// "IREE Vulkan/SPIR-V backend options");
- static llvm::cl::list<std::string> clVulkanTargetTriples{
+ static llvm::cl::opt<std::string> clVulkanTargetTriple(
"iree-vulkan-target-triple",
llvm::cl::desc(
- "Vulkan target triple controlling the SPIR-V environment."),
- };
+ "Vulkan target triple controlling the SPIR-V environment."));
- static llvm::cl::list<std::string> clVulkanTargetEnvs{
+ static llvm::cl::opt<std::string> clVulkanTargetEnv(
"iree-vulkan-target-env",
llvm::cl::desc(
- "Vulkan target environment as #vk.target_env attribute assembly."),
- };
+ "Vulkan target environment as #vk.target_env attribute assembly."));
static llvm::cl::opt<bool> clVulkanIndirectBindings(
"iree-vulkan-experimental-indirect-bindings",
@@ -55,33 +53,14 @@
llvm::cl::init(false));
VulkanSPIRVTargetOptions targetOptions;
-
- int tripleCount = clVulkanTargetTriples.getNumOccurrences();
- int envCount = clVulkanTargetEnvs.getNumOccurrences();
- int tripleIdx = 0;
- int envIdx = 0;
-
- // Get a flat list of target triples and environments following the original
- // order specified via the command line.
- SmallVector<std::string> vulkanTargetTriplesAndEnvs;
- for (int i = 0, e = tripleCount + envCount; i < e; ++i) {
- if (tripleIdx >= tripleCount) {
- vulkanTargetTriplesAndEnvs.push_back(clVulkanTargetEnvs[envIdx++]);
- continue;
- }
- if (envIdx >= envCount) {
- vulkanTargetTriplesAndEnvs.push_back(clVulkanTargetTriples[tripleIdx++]);
- continue;
- }
- if (clVulkanTargetTriples.getPosition(tripleIdx) >
- clVulkanTargetEnvs.getPosition(envIdx)) {
- vulkanTargetTriplesAndEnvs.push_back(clVulkanTargetEnvs[envIdx++]);
- } else {
- vulkanTargetTriplesAndEnvs.push_back(clVulkanTargetTriples[tripleIdx++]);
- }
+ if (!clVulkanTargetEnv.empty()) {
+ // TODO(scotttodd): assert if triple is set too? (mutually exclusive flags)
+ targetOptions.targetTripleOrEnv = clVulkanTargetEnv;
+ } else if (!clVulkanTargetTriple.empty()) {
+ targetOptions.targetTripleOrEnv = clVulkanTargetTriple;
+ } else {
+ targetOptions.targetTripleOrEnv = "unknown-unknown-unknown";
}
- targetOptions.targetTriplesAndEnvs = vulkanTargetTriplesAndEnvs;
-
targetOptions.indirectBindings = clVulkanIndirectBindings;
return targetOptions;
@@ -93,10 +72,12 @@
MLIRContext *context) {
if (!vulkanTargetTripleOrEnv.empty()) {
if (vulkanTargetTripleOrEnv[0] != '#') {
+ // Parse target triple.
return convertTargetEnv(
Vulkan::getTargetEnvForTriple(context, vulkanTargetTripleOrEnv));
}
+ // Parse `#vk.target_env<...` attribute assembly.
if (auto attr = parseAttribute(vulkanTargetTripleOrEnv, context)) {
if (auto vkTargetEnv = llvm::dyn_cast<Vulkan::TargetEnvAttr>(attr)) {
return convertTargetEnv(vkTargetEnv);
@@ -148,19 +129,9 @@
MLIRContext *context, StringRef deviceID, DictionaryAttr deviceConfigAttr,
SmallVectorImpl<IREE::HAL::ExecutableTargetAttr> &executableTargetAttrs)
const override {
- // Select SPIR-V environments to compile for.
- for (std::string targetTripleOrEnv : options_.targetTriplesAndEnvs) {
- executableTargetAttrs.push_back(getExecutableTarget(
- context, getSPIRVTargetEnv(targetTripleOrEnv, context),
- options_.indirectBindings));
- }
-
- // If no environment specified, populate with a minimal target.
- if (executableTargetAttrs.empty()) {
- executableTargetAttrs.push_back(getExecutableTarget(
- context, getSPIRVTargetEnv("unknown-unknown-unknown", context),
- options_.indirectBindings));
- }
+ executableTargetAttrs.push_back(getExecutableTarget(
+ context, getSPIRVTargetEnv(options_.targetTripleOrEnv, context),
+ options_.indirectBindings));
}
IREE::HAL::ExecutableTargetAttr
diff --git a/compiler/src/iree/compiler/Dialect/HAL/Target/VulkanSPIRV/VulkanSPIRVTarget.h b/compiler/src/iree/compiler/Dialect/HAL/Target/VulkanSPIRV/VulkanSPIRVTarget.h
index 5365563..6175f1c 100644
--- a/compiler/src/iree/compiler/Dialect/HAL/Target/VulkanSPIRV/VulkanSPIRVTarget.h
+++ b/compiler/src/iree/compiler/Dialect/HAL/Target/VulkanSPIRV/VulkanSPIRVTarget.h
@@ -10,15 +10,13 @@
#include <functional>
#include <string>
-#include "llvm/ADT/SmallVector.h"
-
namespace mlir::iree_compiler::IREE::HAL {
// Options controlling the SPIR-V translation.
struct VulkanSPIRVTargetOptions {
- // Vulkan target environments, either as #vk.target_env attribute assembly
+ // Vulkan target environment, either as #vk.target_env attribute assembly
// or as a Vulkan target triple.
- llvm::SmallVector<std::string> targetTriplesAndEnvs;
+ std::string targetTripleOrEnv;
// Whether to use indirect bindings for all generated dispatches.
bool indirectBindings = false;
};
diff --git a/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/BUILD.bazel b/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/BUILD.bazel
index 084c2b1..687fa49 100644
--- a/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/BUILD.bazel
+++ b/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/BUILD.bazel
@@ -25,7 +25,6 @@
name = "lit",
srcs = enforce_glob(
[
- "multiple_target_env_conversion.mlir",
"target_env_conversion.mlir",
],
include = ["*.mlir"],
diff --git a/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/CMakeLists.txt b/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/CMakeLists.txt
index 524a0ba..bb5cbe5 100644
--- a/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/CMakeLists.txt
+++ b/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/CMakeLists.txt
@@ -18,7 +18,6 @@
NAME
lit
SRCS
- "multiple_target_env_conversion.mlir"
"target_env_conversion.mlir"
TOOLS
FileCheck
diff --git a/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/multiple_target_env_conversion.mlir b/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/multiple_target_env_conversion.mlir
deleted file mode 100644
index e51577f..0000000
--- a/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/multiple_target_env_conversion.mlir
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN: iree-opt --pass-pipeline='builtin.module(iree-hal-assign-target-devices{targetBackends=vulkan-spirv},iree-hal-transformation-pipeline{serialize-executables=false})' \
-// RUN: --iree-vulkan-target-triple=rdna3-7900xtx-windows \
-// RUN: --iree-vulkan-target-env="#vk.target_env<v1.1, r(120), [VK_KHR_spirv_1_4, VK_KHR_storage_buffer_storage_class], AMD:DiscreteGPU, #vk.caps<maxComputeSharedMemorySize = 16384, maxComputeWorkGroupInvocations = 1024, maxComputeWorkGroupSize = dense<[128, 8, 4]>: vector<3xi32>, subgroupFeatures = 63 : i32, subgroupSize = 4 >>" \
-// RUN: --iree-vulkan-target-triple=valhall-unknown-android31 \
-// RUN: %s | FileCheck %s
-
-// CHECK: #[[RDNA3:.+]] = {{.*}} #spirv.target_env<#spirv.vce<v1.6, [Shader, Float64, Float16, Int64, Int16, Int8, StorageBuffer16BitAccess, StorageUniform16, StoragePushConstant16, StorageBuffer8BitAccess, UniformAndStorageBuffer8BitAccess, StoragePushConstant8, GroupNonUniform, GroupNonUniformVote, GroupNonUniformArithmetic, GroupNonUniformBallot, GroupNonUniformShuffle, GroupNonUniformShuffleRelative, GroupNonUniformClustered, GroupNonUniformQuad, PhysicalStorageBufferAddresses, VariablePointers, VariablePointersStorageBuffer, DotProduct, DotProductInputAll, DotProductInput4x8BitPacked, DotProductInput4x8Bit, CooperativeMatrixKHR],
-// CHECK-SAME: [SPV_KHR_16bit_storage, SPV_KHR_8bit_storage, SPV_KHR_integer_dot_product, SPV_KHR_storage_buffer_storage_class, SPV_KHR_physical_storage_buffer, SPV_KHR_variable_pointers, SPV_KHR_cooperative_matrix]>,
-// CHECK-SAME: api=Vulkan, AMD:DiscreteGPU, #spirv.resource_limits<max_compute_shared_memory_size = 65536, max_compute_workgroup_invocations = 1024, max_compute_workgroup_size = [1024, 1024, 1024], subgroup_size = 64, min_subgroup_size = 32, max_subgroup_size = 64, cooperative_matrix_properties_khr = [#spirv.coop_matrix_props_khr<m_size = 16, n_size = 16, k_size = 16, a_type = i8, b_type = i8, c_type = i32, result_type = i32, acc_sat = false, scope = <Subgroup>>, #spirv.coop_matrix_props_khr<m_size = 16, n_size = 16, k_size = 16, a_type = f16, b_type = f16, c_type = f16, result_type = f16, acc_sat = false, scope = <Subgroup>>, #spirv.coop_matrix_props_khr<m_size = 16, n_size = 16, k_size = 16, a_type = f16, b_type = f16, c_type = f32, result_type = f32, acc_sat = false, scope = <Subgroup>>]>>
-
-// CHECK: #[[ENV:.+]] = {{.*}} #spirv.target_env<#spirv.vce<v1.4, [Shader, GroupNonUniform, GroupNonUniformVote, GroupNonUniformArithmetic, GroupNonUniformBallot, GroupNonUniformShuffle, GroupNonUniformShuffleRelative],
-// CHECK-SAME: [SPV_KHR_storage_buffer_storage_class]>,
-// CHECK-SAME: api=Vulkan, AMD:DiscreteGPU, #spirv.resource_limits<max_compute_workgroup_invocations = 1024, max_compute_workgroup_size = [128, 8, 4], subgroup_size = 4, cooperative_matrix_properties_khr = []>>
-
-// CHECK: #[[VALHALL:.+]] = {{.*}} #spirv.target_env<#spirv.vce<v1.4, [Shader, Float16, Int16, Int8, StorageBuffer16BitAccess, StorageUniform16, StoragePushConstant16, StorageBuffer8BitAccess, UniformAndStorageBuffer8BitAccess, StoragePushConstant8, GroupNonUniform, GroupNonUniformVote, GroupNonUniformArithmetic, GroupNonUniformBallot, GroupNonUniformShuffle, GroupNonUniformShuffleRelative, GroupNonUniformClustered, GroupNonUniformQuad, VariablePointers, VariablePointersStorageBuffer, DotProduct, DotProductInputAll, DotProductInput4x8BitPacked, DotProductInput4x8Bit],
-// CHECK-SAME: [SPV_KHR_16bit_storage, SPV_KHR_8bit_storage, SPV_KHR_integer_dot_product, SPV_KHR_storage_buffer_storage_class, SPV_KHR_variable_pointers]>,
-// CHECK-SAME: api=Vulkan, ARM:IntegratedGPU, #spirv.resource_limits<max_compute_shared_memory_size = 32768, max_compute_workgroup_invocations = 512, max_compute_workgroup_size = [512, 512, 512], subgroup_size = 16, cooperative_matrix_properties_khr = []>>
-
-// Verify that the order of target environments matches what the user specified.
-
-// CHECK: [#[[RDNA3]], #[[ENV]], #[[VALHALL]]]
-
-stream.executable public @reduce_dispatch {
- stream.executable.export @reduce_dispatch workgroups(%arg0: index) -> (index, index, index) {
- %x, %y, %z = flow.dispatch.workgroup_count_from_dag_root %arg0
- stream.return %x, %y, %z : index, index, index
- }
- builtin.module {
- func.func @reduce_dispatch(%arg0_binding: !stream.binding, %arg1_binding: !stream.binding) {
- %c0 = arith.constant 0 : index
- %arg0 = stream.binding.subspan %arg0_binding[%c0] : !stream.binding -> !flow.dispatch.tensor<readonly:tensor<16xf32>>
- %arg1 = stream.binding.subspan %arg1_binding[%c0] : !stream.binding -> !flow.dispatch.tensor<writeonly:tensor<f32>>
- %0 = tensor.empty() : tensor<f32>
- %1 = flow.dispatch.tensor.load %arg0, offsets=[0], sizes=[16], strides=[1] : !flow.dispatch.tensor<readonly:tensor<16xf32>> -> tensor<16xf32>
- %3 = linalg.generic {indexing_maps = [affine_map<(d0) -> (d0)>, affine_map<(d0) -> ()>], iterator_types = ["reduction"]} ins(%1 : tensor<16xf32>) outs(%0 : tensor<f32>) {
- ^bb0(%arg2: f32, %arg3: f32):
- %4 = arith.addf %arg2, %arg3 : f32
- linalg.yield %4 : f32
- } -> tensor<f32>
- flow.dispatch.tensor.store %3, %arg1, offsets=[], sizes=[], strides=[] : tensor<f32> -> !flow.dispatch.tensor<writeonly:tensor<f32>>
- return
- }
- }
-}
diff --git a/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/target_env_conversion.mlir b/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/target_env_conversion.mlir
index 69d1010..3a23031 100644
--- a/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/target_env_conversion.mlir
+++ b/compiler/src/iree/compiler/Dialect/Vulkan/Utils/test/target_env_conversion.mlir
@@ -7,6 +7,7 @@
// RUN: iree-opt --pass-pipeline='builtin.module(iree-hal-assign-target-devices{targetBackends=vulkan-spirv},iree-hal-transformation-pipeline{serialize-executables=false})' --iree-vulkan-target-triple=m1-moltenvk-macos %s | FileCheck %s --check-prefix=M1
// RUN: iree-opt --pass-pipeline='builtin.module(iree-hal-assign-target-devices{targetBackends=vulkan-spirv},iree-hal-transformation-pipeline{serialize-executables=false})' --iree-vulkan-target-triple=arc-770-windows %s | FileCheck %s --check-prefix=ARC
// RUN: iree-opt --pass-pipeline='builtin.module(iree-hal-assign-target-devices{targetBackends=vulkan-spirv},iree-hal-transformation-pipeline{serialize-executables=false})' --iree-vulkan-target-triple=pascal-1080-windows %s | FileCheck %s --check-prefix=PASCAL
+// RUN: iree-opt --pass-pipeline='builtin.module(iree-hal-assign-target-devices{targetBackends=vulkan-spirv},iree-hal-transformation-pipeline{serialize-executables=false})' --iree-vulkan-target-env="#vk.target_env<v1.1, r(120), [VK_KHR_spirv_1_4, VK_KHR_storage_buffer_storage_class], AMD:DiscreteGPU, #vk.caps<maxComputeSharedMemorySize = 16384, maxComputeWorkGroupInvocations = 1024, maxComputeWorkGroupSize = dense<[128, 8, 4]>: vector<3xi32>, subgroupFeatures = 63 : i32, subgroupSize = 4 >>" %s | FileCheck %s --check-prefix=ENV
// TODO(antiagainst): Passing in lenghty strings as command-line options is not
// optimal. We should consider creating a dedicated test pass to pick up
@@ -56,6 +57,11 @@
// PASCAL-SAME: [SPV_KHR_16bit_storage, SPV_KHR_8bit_storage, SPV_KHR_integer_dot_product, SPV_KHR_storage_buffer_storage_class, SPV_KHR_physical_storage_buffer, SPV_KHR_variable_pointers, SPV_KHR_cooperative_matrix]>,
// PASCAL-SAME: api=Vulkan, NVIDIA:DiscreteGPU, #spirv.resource_limits<max_compute_shared_memory_size = 49152, max_compute_workgroup_invocations = 1536, max_compute_workgroup_size = [1536, 1024, 64], min_subgroup_size = 32, max_subgroup_size = 32, cooperative_matrix_properties_khr = []>>}>
+// ENV: #spirv.target_env<#spirv.vce<v1.4,
+// ENV-SAME: [Shader, GroupNonUniform, GroupNonUniformVote, GroupNonUniformArithmetic, GroupNonUniformBallot, GroupNonUniformShuffle, GroupNonUniformShuffleRelative],
+// ENV-SAME: [SPV_KHR_storage_buffer_storage_class]>,
+// ENV-SAME: api=Vulkan, AMD:DiscreteGPU, #spirv.resource_limits<max_compute_workgroup_invocations = 1024, max_compute_workgroup_size = [128, 8, 4], subgroup_size = 4, cooperative_matrix_properties_khr = []>>
+
stream.executable public @reduce_dispatch {
stream.executable.export @reduce_dispatch workgroups(%arg0: index) -> (index, index, index) {
%x, %y, %z = flow.dispatch.workgroup_count_from_dag_root %arg0