Add a suite of tests for WebAssembly compilation. (#8516)
This adds a new test suite to `iree/test/e2e/xla_ops` that uses IREE's WebAssembly target via `-iree-hal-target-backends=dylib-llvm-aot -iree-llvm-target-triple=wasm32-unknown-emscripten` (I'd use `llvm` as the target name, but our infra is hardcoded to the dylib name).
Since we don't have a native WebAssembly HAL driver yet and the browser WebAssembly use is still experimental (and in no way integrated into our common build/test infra), these new "tests" are _just_ `iree_bytecode_module` targets that run at build time. The new tests don't actually use the check framework for "e2e" execution testing. Reusing the existing infra in this hacky way seems easiest to maintain and gives us a nice transition to enabling execution testing once a native Wasm HAL driver is added.
I'd like to add similar coverage for other in-development compiler configurations (WebGPU) and expand to include more test suites (`test/e2e/tosa_ops/`, [google/iree-samples /tflitehub](https://github.com/google/iree-samples/tree/main/tflitehub), etc.).
(there was some discussion about how to add this test coverage [on Discord here](https://discord.com/channels/689900678990135345/782059441641881630/951179647691919360))
diff --git a/build_tools/bazel/iree_bytecode_module.bzl b/build_tools/bazel/iree_bytecode_module.bzl
index 6722ba6..4bd0ef8 100644
--- a/build_tools/bazel/iree_bytecode_module.bzl
+++ b/build_tools/bazel/iree_bytecode_module.bzl
@@ -16,7 +16,7 @@
module = None,
flags = ["-iree-mlir-to-vm-bytecode-module"],
translate_tool = "//iree/tools:iree-translate",
- embedded_linker_tool = "@llvm-project//lld:lld",
+ linker_tool = "@llvm-project//lld:lld",
opt_tool = "//iree/tools:iree-opt",
opt_flags = [],
c_identifier = "",
@@ -30,7 +30,7 @@
translation and backend flags are passed automatically.
translate_tool: the compiler to use to generate the module.
Defaults to iree-translate.
- embedded_linker_tool: the embedded linker to use.
+ linker_tool: the linker to use.
Defaults to the lld from the llvm-project directory.
opt_tool: Defaulting to iree-opt. Tool used to preprocess the source file
if opt_flags is specified.
@@ -74,12 +74,13 @@
" ".join([
"$(location %s)" % (translate_tool),
" ".join(flags),
- "-iree-llvm-embedded-linker-path=$(location %s)" % (embedded_linker_tool),
+ "-iree-llvm-embedded-linker-path=$(location %s)" % (linker_tool),
+ "-iree-llvm-system-linker-path=$(location %s)" % (linker_tool),
"-o $(location %s)" % (module),
"$(location %s)" % (translate_src),
]),
]),
- tools = [translate_tool, embedded_linker_tool],
+ tools = [translate_tool, linker_tool],
message = "Compiling IREE module %s..." % (name),
output_to_bindir = 1,
**kwargs
diff --git a/build_tools/bazel/iree_check_test.bzl b/build_tools/bazel/iree_check_test.bzl
index a72fe41..67832e9 100644
--- a/build_tools/bazel/iree_check_test.bzl
+++ b/build_tools/bazel/iree_check_test.bzl
@@ -19,7 +19,7 @@
name,
src,
target_backend,
- driver,
+ driver = None,
compiler_flags = [],
runner_args = [],
opt_tool = "//iree/tools:iree-opt",
@@ -34,7 +34,9 @@
name: name of the generated test.
src: source mlir file containing the module.
target_backend: target backend to compile for.
- driver: driver to run the module with.
+ driver: driver to run the module with. This can be omitted to test only
+ compilation, but consider omiting the driver as a hacky abuse of the
+ rule since compilation on its own not use iree-check-module.
compiler_flags: additional flags to pass to the compiler. Bytecode translation and backend
flags are passed automatically.
runner_args: additional runner_args to pass to iree-check-module. The driver and input file
@@ -67,6 +69,9 @@
visibility = ["//visibility:private"],
)
+ if not driver:
+ return
+
native_test(
name = name,
args = [
@@ -84,7 +89,7 @@
name,
srcs,
target_backend,
- driver,
+ driver = None,
compiler_flags = [],
runner_args = [],
opt_tool = "//iree/tools:iree-opt",
@@ -101,7 +106,9 @@
name: name of the generated test suite.
srcs: source mlir files containing the module.
target_backend: target backend to compile for.
- driver: driver to run the module with.
+ driver: driver to run the module with. This can be omitted to test only
+ compilation, but consider omiting the driver as a hacky abuse of the
+ rule since compilation on its own not use iree-check-module.
compiler_flags: additional flags to pass to the compiler. Bytecode translation and backend
flags are passed automatically.
runner_args: additional runner_args to pass to the underlying iree-check-module tests. The
@@ -145,6 +152,10 @@
**kwargs
)
tests.append(test_name)
+
+ if not driver:
+ return
+
native.test_suite(
name = name,
tests = tests,
diff --git a/build_tools/bazel_to_cmake/bazel_to_cmake_converter.py b/build_tools/bazel_to_cmake/bazel_to_cmake_converter.py
index c166e49..6de746e 100644
--- a/build_tools/bazel_to_cmake/bazel_to_cmake_converter.py
+++ b/build_tools/bazel_to_cmake/bazel_to_cmake_converter.py
@@ -536,7 +536,7 @@
name,
srcs,
target_backend,
- driver,
+ driver=None,
compiler_flags=None,
target_backends_and_drivers=None,
runner_args=None,
diff --git a/build_tools/cmake/iree_bytecode_module.cmake b/build_tools/cmake/iree_bytecode_module.cmake
index 24d8bbc..4ea25d3 100644
--- a/build_tools/cmake/iree_bytecode_module.cmake
+++ b/build_tools/cmake/iree_bytecode_module.cmake
@@ -110,8 +110,9 @@
# If an LLVM CPU backend is enabled, supply the linker tool.
if(IREE_LLD_TARGET)
- iree_get_executable_path(_EMBEDDED_LINKER_TOOL_EXECUTABLE "lld")
- list(APPEND _ARGS "-iree-llvm-embedded-linker-path=\"${_EMBEDDED_LINKER_TOOL_EXECUTABLE}\"")
+ iree_get_executable_path(_LINKER_TOOL_EXECUTABLE "lld")
+ list(APPEND _ARGS "-iree-llvm-system-linker-path=\"${_LINKER_TOOL_EXECUTABLE}\"")
+ list(APPEND _ARGS "-iree-llvm-embedded-linker-path=\"${_LINKER_TOOL_EXECUTABLE}\"")
endif()
# Depending on the binary instead of the target here given we might not have
@@ -126,7 +127,7 @@
# trigger rebuilding.
DEPENDS
${_TRANSLATE_TOOL_EXECUTABLE}
- ${_EMBEDDED_LINKER_TOOL_EXECUTABLE}
+ ${_LINKER_TOOL_EXECUTABLE}
${_TRANSLATE_SRC}
VERBATIM
)
diff --git a/build_tools/cmake/iree_check_test.cmake b/build_tools/cmake/iree_check_test.cmake
index 05d4f4a..8972fa0 100644
--- a/build_tools/cmake/iree_check_test.cmake
+++ b/build_tools/cmake/iree_check_test.cmake
@@ -23,7 +23,7 @@
${ARGN}
)
- if(ANDROID)
+ if(ANDROID AND NOT _RULE_FLAGS MATCHES "iree-llvm-target-triple")
# Android's CMake toolchain defines some variables that we can use to infer
# the appropriate target triple from the configured settings:
# https://developer.android.com/ndk/guides/cmake#android_platform
@@ -77,7 +77,9 @@
# NAME: Name of the target
# SRC: mlir source file to be compiled to an IREE module.
# TARGET_BACKEND: target backend to compile for.
-# DRIVER: driver to run the module with.
+# DRIVER: driver to run the module with. This can be omitted to test only
+# compilation, but consider omiting the driver as a hacky abuse of the
+# rule since compilation on its own not use iree-check-module.
# COMPILER_FLAGS: additional flags to pass to the compiler. Bytecode
# translation and backend flags are passed automatically.
# RUNNER_ARGS: additional args to pass to iree-check-module. The driver
@@ -180,6 +182,10 @@
add_dependencies(iree-test-deps "${_NAME}")
+ if(NOT DEFINED _RULE_DRIVER)
+ return()
+ endif()
+
iree_native_test(
NAME
"${_RULE_NAME}"
@@ -208,7 +214,9 @@
# NAME: name of the generated test suite.
# SRCS: source mlir files containing the module.
# TARGET_BACKEND: target backend to compile for.
-# DRIVER: driver to run the module with.
+# DRIVER: driver to run the module with. This can be omitted to test only
+# compilation, but consider omiting the driver as a hacky abuse of the
+# rule since compilation on its own not use iree-check-module.
# COMPILER_FLAGS: additional flags to pass to the compiler. Bytecode
# translation and backend flags are passed automatically.
# RUNNER_ARGS: additional args to pass to the underlying iree-check-module
@@ -241,13 +249,18 @@
# Omit tests for which the specified driver or target backend is not enabled.
# This overlaps with directory exclusions and other filtering mechanisms.
- string(TOUPPER ${_RULE_DRIVER} _UPPERCASE_DRIVER)
- string(REPLACE "-" "_" _NORMALIZED_DRIVER ${_UPPERCASE_DRIVER})
- if(NOT DEFINED IREE_HAL_DRIVER_${_NORMALIZED_DRIVER})
- message(SEND_ERROR "Unknown driver '${_RULE_DRIVER}'. Check IREE_HAL_DRIVER_* options.")
- endif()
- if(NOT IREE_HAL_DRIVER_${_NORMALIZED_DRIVER})
- return()
+ #
+ # Note: omitting the DRIVER arg is allowed (though it is a hack). If it is
+ # omitted, we don't need to test for a driver being enabled.
+ if(DEFINED _RULE_DRIVER)
+ string(TOUPPER ${_RULE_DRIVER} _UPPERCASE_DRIVER)
+ string(REPLACE "-" "_" _NORMALIZED_DRIVER ${_UPPERCASE_DRIVER})
+ if(NOT DEFINED IREE_HAL_DRIVER_${_NORMALIZED_DRIVER})
+ message(SEND_ERROR "Unknown driver '${_RULE_DRIVER}'. Check IREE_HAL_DRIVER_* options.")
+ endif()
+ if(NOT IREE_HAL_DRIVER_${_NORMALIZED_DRIVER})
+ return()
+ endif()
endif()
string(TOUPPER ${_RULE_TARGET_BACKEND} _UPPERCASE_TARGET_BACKEND)
string(REPLACE "-" "_" _NORMALIZED_TARGET_BACKEND ${_UPPERCASE_TARGET_BACKEND})
diff --git a/iree/test/e2e/xla_ops/BUILD b/iree/test/e2e/xla_ops/BUILD
index 20e3b73..616ecb8 100644
--- a/iree/test/e2e/xla_ops/BUILD
+++ b/iree/test/e2e/xla_ops/BUILD
@@ -82,7 +82,7 @@
],
include = ["*.mlir"],
exclude = [
- "round.mlir",
+ "round.mlir", # TODO(#7618): Enable once supported.
],
),
compiler_flags = ["-iree-input-type=mhlo"],
@@ -99,7 +99,7 @@
target_backend = "cuda",
)
-# # Run cuda tests using stream command buffer
+# Run cuda tests using stream command buffer
iree_check_single_backend_test_suite(
name = "check_cuda_streams",
srcs = enforce_glob(
@@ -163,7 +163,7 @@
],
include = ["*.mlir"],
exclude = [
- "round.mlir",
+ "round.mlir", # TODO(#7618): Enable once supported.
],
),
compiler_flags = ["-iree-input-type=mhlo"],
@@ -243,9 +243,7 @@
],
include = ["*.mlir"],
exclude = [
- #TODO(#7415): Enable this after failures with bazel bot
- #and cmake-swiftshared bot are addressed
- "round.mlir",
+ "round.mlir", # TODO(#7618): Enable once supported.
],
),
compiler_flags = ["-iree-input-type=mhlo"],
@@ -313,8 +311,8 @@
include = ["*.mlir"],
exclude = [
"exponential_fp16.mlir",
- "fft.mlir", # TODO(#6601): Eanble the test.
- "round.mlir",
+ "fft.mlir", # TODO(#6601): Enable the test.
+ "round.mlir", # TODO(#7618): Enable once supported.
"rng_uniform.mlir", # TODO(#6995): Enable the test.
"rng_normal.mlir", # TODO(#6995): Enable the test.
],
@@ -387,7 +385,7 @@
exclude = [
"bitcast_convert.mlir",
"exponential_fp16.mlir",
- "round.mlir",
+ "round.mlir", # TODO(#7618): Enable once supported.
],
),
compiler_flags = ["-iree-input-type=mhlo"],
@@ -395,6 +393,88 @@
target_backend = "vulkan-spirv",
)
+# Check WebAssembly compilation (LLVM backend with wasm target triple).
+# Note:
+# * no 'driver' arg is set, so this does not test execution
+# * the test suite name is missing "_driver" from "check_target_driver"
+# * this isn't an "end to end" test suite in the same sense as the other
+# test suites in this file, but the test coverage is still useful
+# Hopefully at some point we can build WebAssembly execution testing into our
+# infrastructure and this will no longer bend our testing definitions as much.
+iree_check_single_backend_test_suite(
+ name = "check_wasm-llvm-aot",
+ srcs = enforce_glob(
+ # keep sorted
+ [
+ "abs.mlir",
+ "add.mlir",
+ "batch_norm_inference.mlir",
+ "bitcast_convert.mlir",
+ "broadcast.mlir",
+ "broadcast_add.mlir",
+ "broadcast_in_dim.mlir",
+ "clamp.mlir",
+ "compare.mlir",
+ "concatenate.mlir",
+ "constant.mlir",
+ "convert.mlir",
+ "convolution.mlir",
+ "cosine.mlir",
+ "divide.mlir",
+ "dot.mlir",
+ "dot_general.mlir",
+ "dynamic_slice.mlir",
+ "dynamic_update_slice.mlir",
+ "exponential.mlir",
+ "exponential_fp16.mlir",
+ "exponential_minus_one.mlir",
+ "fft.mlir",
+ "finite.mlir",
+ "floor.mlir",
+ "gather.mlir",
+ "iota.mlir",
+ "log.mlir",
+ "log_plus_one.mlir",
+ "multiply.mlir",
+ "negate.mlir",
+ "pad.mlir",
+ "pow.mlir",
+ "reduce.mlir",
+ "reduce_window.mlir",
+ "reshape.mlir",
+ "reverse.mlir",
+ "rng_normal.mlir",
+ "rng_uniform.mlir",
+ "rsqrt.mlir",
+ "scatter.mlir",
+ "scatter_dynamic.mlir",
+ "select.mlir",
+ "sine.mlir",
+ "slice.mlir",
+ "sort.mlir",
+ "sqrt.mlir",
+ "subtract.mlir",
+ "tanh.mlir",
+ "torch_index_select.mlir",
+ "transpose.mlir",
+ "while.mlir",
+ ],
+ include = ["*.mlir"],
+ exclude = [
+ "round.mlir", # TODO(#7618): Enable once supported.
+ "maximum.mlir", # TODO(#8514): Fix compiler crash.
+ "minimum.mlir", # TODO(#8514): Fix compiler crash.
+ "remainder.mlir", # TODO(#8514): Fix compiler crash.
+ ],
+ ),
+ compiler_flags = [
+ "-iree-input-type=mhlo",
+ "-iree-llvm-target-triple=wasm32-unknown-emscripten",
+ ],
+ # driver = "wasm", # No driver yet, only test compilation.
+ target_backend = "dylib-llvm-aot",
+)
+
test_suite(
name = "check",
tests = [
diff --git a/iree/test/e2e/xla_ops/CMakeLists.txt b/iree/test/e2e/xla_ops/CMakeLists.txt
index 05236c9..d83a006 100644
--- a/iree/test/e2e/xla_ops/CMakeLists.txt
+++ b/iree/test/e2e/xla_ops/CMakeLists.txt
@@ -355,4 +355,67 @@
"-iree-input-type=mhlo"
)
+iree_check_single_backend_test_suite(
+ NAME
+ check_wasm-llvm-aot
+ SRCS
+ "abs.mlir"
+ "add.mlir"
+ "batch_norm_inference.mlir"
+ "bitcast_convert.mlir"
+ "broadcast.mlir"
+ "broadcast_add.mlir"
+ "broadcast_in_dim.mlir"
+ "clamp.mlir"
+ "compare.mlir"
+ "concatenate.mlir"
+ "constant.mlir"
+ "convert.mlir"
+ "convolution.mlir"
+ "cosine.mlir"
+ "divide.mlir"
+ "dot.mlir"
+ "dot_general.mlir"
+ "dynamic_slice.mlir"
+ "dynamic_update_slice.mlir"
+ "exponential.mlir"
+ "exponential_fp16.mlir"
+ "exponential_minus_one.mlir"
+ "fft.mlir"
+ "finite.mlir"
+ "floor.mlir"
+ "gather.mlir"
+ "iota.mlir"
+ "log.mlir"
+ "log_plus_one.mlir"
+ "multiply.mlir"
+ "negate.mlir"
+ "pad.mlir"
+ "pow.mlir"
+ "reduce.mlir"
+ "reduce_window.mlir"
+ "reshape.mlir"
+ "reverse.mlir"
+ "rng_normal.mlir"
+ "rng_uniform.mlir"
+ "rsqrt.mlir"
+ "scatter.mlir"
+ "scatter_dynamic.mlir"
+ "select.mlir"
+ "sine.mlir"
+ "slice.mlir"
+ "sort.mlir"
+ "sqrt.mlir"
+ "subtract.mlir"
+ "tanh.mlir"
+ "torch_index_select.mlir"
+ "transpose.mlir"
+ "while.mlir"
+ TARGET_BACKEND
+ "dylib-llvm-aot"
+ COMPILER_FLAGS
+ "-iree-input-type=mhlo"
+ "-iree-llvm-target-triple=wasm32-unknown-emscripten"
+)
+
### BAZEL_TO_CMAKE_PRESERVES_ALL_CONTENT_BELOW_THIS_LINE ###