-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[mlir] Add mlir_arm_runner_utils
library for use in integration tests
#78583
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
This adds a new `mlir_arm_runner_utils` library that contains utils specific to Arm/AArch64. This is for use in MLIR integration tests. This initial patch adds `setArmVLBits()` and `setArmSVLBits()`. This allows changing vector length or streaming vector length at runtime (or setting it to a known minimum, i.e. 128-bits).
@llvm/pr-subscribers-mlir-sve @llvm/pr-subscribers-mlir-sme Author: Benjamin Maxwell (MacDue) ChangesThis adds a new This initial patch adds Full diff: https://github.com/llvm/llvm-project/pull/78583.diff 6 Files Affected:
diff --git a/mlir/lib/ExecutionEngine/ArmRunnerUtils.cpp b/mlir/lib/ExecutionEngine/ArmRunnerUtils.cpp
new file mode 100644
index 00000000000000..e619c923453cf3
--- /dev/null
+++ b/mlir/lib/ExecutionEngine/ArmRunnerUtils.cpp
@@ -0,0 +1,60 @@
+//===- ArmRunnerUtils.cpp - Utilities for configuring architecture properties //
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include <iostream>
+#include <stdint.h>
+#include <string_view>
+
+#if (defined(_WIN32) || defined(__CYGWIN__))
+#define MLIR_ARMRUNNERUTILS_EXPORTED __declspec(dllexport)
+#else
+#define MLIR_ARMRUNNERUTILS_EXPORTED __attribute__((visibility("default")))
+#endif
+
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
+
+extern "C" {
+
+#define PR_VL_LEN_MASK 0xffff
+
+#ifndef PR_SVE_SET_VL
+#define PR_SVE_SET_VL 50
+#endif
+
+#ifndef PR_SME_SET_VL
+#define PR_SME_SET_VL 63
+#endif
+
+static void setArmVectorLength(std::string_view helper_name, int option,
+ int bits) {
+#if defined(__linux__) && defined(__aarch64__)
+ if (bits < 128 || bits % 128 != 0 || bits > 2048) {
+ std::cerr << "[error] Invalid aarch64 vector length!" << std::endl;
+ abort();
+ }
+ uint32_t vl = bits / 8;
+ if (prctl(option, vl & PR_VL_LEN_MASK) == -1) {
+ std::cerr << "[error] prctl failed!" << std::endl;
+ abort();
+ }
+#else
+ std::cerr << "[error] " << helper_name << " is unsupported!" << std::endl;
+ abort();
+#endif
+}
+
+void MLIR_ARMRUNNERUTILS_EXPORTED setArmVLBits(uint32_t bits) {
+ setArmVectorLength(__func__, PR_SVE_SET_VL, bits);
+}
+
+void MLIR_ARMRUNNERUTILS_EXPORTED setArmSVLBits(uint32_t bits) {
+ setArmVectorLength(__func__, PR_SME_SET_VL, bits);
+}
+}
diff --git a/mlir/lib/ExecutionEngine/CMakeLists.txt b/mlir/lib/ExecutionEngine/CMakeLists.txt
index 2f391b7698cbb0..b7e448d5417ea9 100644
--- a/mlir/lib/ExecutionEngine/CMakeLists.txt
+++ b/mlir/lib/ExecutionEngine/CMakeLists.txt
@@ -2,6 +2,7 @@
# is a big dependency which most don't need.
set(LLVM_OPTIONAL_SOURCES
+ ArmRunnerUtils.cpp
ArmSMEStubs.cpp
AsyncRuntime.cpp
CRunnerUtils.cpp
@@ -186,6 +187,10 @@ if(LLVM_ENABLE_PIC)
ArmSMEStubs.cpp)
target_compile_definitions(mlir_arm_sme_abi_stubs PRIVATE mlir_arm_sme_abi_stubs_EXPORTS)
+ add_mlir_library(mlir_arm_runner_utils
+ SHARED
+ ArmRunnerUtils.cpp)
+
if(MLIR_ENABLE_CUDA_RUNNER)
# Configure CUDA support. Using check_language first allows us to give a
# custom error message.
diff --git a/mlir/test/CMakeLists.txt b/mlir/test/CMakeLists.txt
index 8ce030feeded92..6724dd4bdd1bcd 100644
--- a/mlir/test/CMakeLists.txt
+++ b/mlir/test/CMakeLists.txt
@@ -153,6 +153,10 @@ if (MLIR_RUN_ARM_SME_TESTS AND NOT ARM_SME_ABI_ROUTINES_SHLIB)
list(APPEND MLIR_TEST_DEPENDS mlir_arm_sme_abi_stubs)
endif()
+if (MLIR_RUN_ARM_SVE_TESTS OR MLIR_RUN_ARM_SME_TESTS)
+ list(APPEND MLIR_TEST_DEPENDS mlir_arm_runner_utils)
+endif()
+
list(APPEND MLIR_TEST_DEPENDS MLIRUnitTests)
if(LLVM_BUILD_EXAMPLES)
diff --git a/mlir/test/Integration/Dialect/Vector/CPU/ArmSME/test-setArmSVLBits.mlir b/mlir/test/Integration/Dialect/Vector/CPU/ArmSME/test-setArmSVLBits.mlir
new file mode 100644
index 00000000000000..3e7e72df665c3f
--- /dev/null
+++ b/mlir/test/Integration/Dialect/Vector/CPU/ArmSME/test-setArmSVLBits.mlir
@@ -0,0 +1,76 @@
+// DEFINE: %{entry_point} = main
+// DEFINE: %{compile} = mlir-opt %s -convert-arm-sme-to-llvm \
+// DEFINE: -cse -canonicalize -test-lower-to-llvm
+// DEFINE: %{run} = %mcr_aarch64_cmd \
+// DEFINE: -march=aarch64 -mattr=+sve,+sme \
+// DEFINE: -e %{entry_point} -entry-point-result=void \
+// DEFINE: -shared-libs=%mlir_runner_utils,%mlir_c_runner_utils,%mlir_arm_runner_utils
+
+// RUN: %{compile} | %{run} | FileCheck %s
+
+func.func @checkSVL() {
+ %svl_b = arm_sme.streaming_vl <byte>
+ %svl_h = arm_sme.streaming_vl <half>
+ %svl_w = arm_sme.streaming_vl <word>
+ %svl_d = arm_sme.streaming_vl <double>
+ vector.print str "SVL.b"
+ vector.print %svl_b : index
+ vector.print str "SVL.h"
+ vector.print %svl_h : index
+ vector.print str "SVL.w"
+ vector.print %svl_w : index
+ vector.print str "SVL.d"
+ vector.print %svl_d : index
+ return
+}
+
+func.func @main() {
+ // CHECK: SVL.b
+ // CHECK-NEXT: 16
+ //
+ // CHECK-NEXT: SVL.h
+ // CHECK-NEXT: 8
+ //
+ // CHECK-NEXT: SVL.w
+ // CHECK-NEXT: 4
+ //
+ // CHECK-NEXT: SVL.d
+ // CHECK-NEXT: 2
+ %c128 = arith.constant 128 : i32
+ func.call @setArmSVLBits(%c128) : (i32) -> ()
+ func.call @checkSVL() : () -> ()
+
+ // CHECK: SVL.b
+ // CHECK-NEXT: 32
+ //
+ // CHECK-NEXT: SVL.h
+ // CHECK-NEXT: 16
+ //
+ // CHECK-NEXT: SVL.w
+ // CHECK-NEXT: 8
+ //
+ // CHECK-NEXT: SVL.d
+ // CHECK-NEXT: 4
+ %c256 = arith.constant 256 : i32
+ func.call @setArmSVLBits(%c256) : (i32) -> ()
+ func.call @checkSVL() : () -> ()
+
+ // CHECK: SVL.b
+ // CHECK-NEXT: 64
+ //
+ // CHECK-NEXT: SVL.h
+ // CHECK-NEXT: 32
+ //
+ // CHECK-NEXT: SVL.w
+ // CHECK-NEXT: 16
+ //
+ // CHECK-NEXT: SVL.d
+ // CHECK-NEXT: 8
+ %c512 = arith.constant 512 : i32
+ func.call @setArmSVLBits(%c512) : (i32) -> ()
+ func.call @checkSVL() : () -> ()
+
+ return
+}
+
+func.func private @setArmSVLBits(%bits : i32)
diff --git a/mlir/test/Integration/Dialect/Vector/CPU/ArmSME/test-setArmVLBits.mlir b/mlir/test/Integration/Dialect/Vector/CPU/ArmSME/test-setArmVLBits.mlir
new file mode 100644
index 00000000000000..ad7a29d47d068e
--- /dev/null
+++ b/mlir/test/Integration/Dialect/Vector/CPU/ArmSME/test-setArmVLBits.mlir
@@ -0,0 +1,38 @@
+// DEFINE: %{entry_point} = main
+// DEFINE: %{compile} = mlir-opt %s -convert-arm-sme-to-llvm \
+// DEFINE: -cse -canonicalize -test-lower-to-llvm
+// DEFINE: %{run} = %mcr_aarch64_cmd \
+// DEFINE: -march=aarch64 -mattr=+sve,+sme \
+// DEFINE: -e %{entry_point} -entry-point-result=void \
+// DEFINE: -shared-libs=%mlir_runner_utils,%mlir_c_runner_utils,%mlir_arm_runner_utils
+
+// RUN: %{compile} | %{run} | FileCheck %s
+
+/// Note: This is included in the SME tests rather than the SVE tests as it is
+/// safe to assume the SME tests will be ran on an emulator, so will be able to
+/// change the vector length.
+
+func.func @checkVScale() {
+ %vscale = vector.vscale
+ vector.print str "vscale"
+ vector.print %vscale : index
+ return
+}
+
+func.func @main() {
+ // CHECK: vscale
+ // CHECK-NEXT: 1
+ %c128 = arith.constant 128 : i32
+ func.call @setArmVLBits(%c128) : (i32) -> ()
+ func.call @checkVScale() : () -> ()
+
+ // CHECK: vscale
+ // CHECK-NEXT: 2
+ %c256 = arith.constant 256 : i32
+ func.call @setArmVLBits(%c256) : (i32) -> ()
+ func.call @checkVScale() : () -> ()
+
+ return
+}
+
+func.func private @setArmVLBits(%bits : i32)
diff --git a/mlir/test/lit.cfg.py b/mlir/test/lit.cfg.py
index 0a1ea1d16da452..38e65e4549c559 100644
--- a/mlir/test/lit.cfg.py
+++ b/mlir/test/lit.cfg.py
@@ -135,6 +135,9 @@ def add_runtime(name):
if config.enable_sycl_runner:
tools.extend([add_runtime("mlir_sycl_runtime")])
+if config.mlir_run_arm_sve_tests or config.mlir_run_arm_sme_tests:
+ tools.extend([add_runtime("mlir_arm_runner_utils")])
+
if config.mlir_run_arm_sme_tests:
config.substitutions.append(
(
|
These tests assume the hardware's vector length is >= the max VL they set. This cannot be guaranteed for all hardware configurations unless these tests are emulated.
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!
Thanks, this is going to be so helpful!
mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/Emulated/test-setArmVLBits.mlir
Show resolved
Hide resolved
mlir/test/Integration/Dialect/Vector/CPU/ArmSVE/Emulated/test-setArmVLBits.mlir
Show resolved
Hide resolved
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.
thanks for patch Ben this is cool!
mlir/test/Integration/Dialect/Vector/CPU/ArmSME/Emulated/test-setArmSVLBits.mlir
Outdated
Show resolved
Hide resolved
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.
I wonder if this belongs under the Vector dialect integration tests given it's more geared towards ArmSME (bar vector.print
of course) and whether this would be a good opportunity to create a place for ArmSME dialect integration tests?
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.
I'm not really sure doing so would be that helpful. This is just a very small test (and it still vector related as it's checking the vector length, just via an ArmSME helper). Future tests I'd like to include here will use more vector ops (e.g. transfer_read/write), adding another place to look for similar tests may just be a little confusing.
This adds a new
mlir_arm_runner_utils
library that contains utils specific to Arm/AArch64. This is for use in MLIR integration tests.This initial patch adds
setArmVLBits()
andsetArmSVLBits()
. This allows changing vector length or streaming vector length at runtime (or setting it to a known minimum, i.e. 128-bits).