Skip to content

[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

Merged
merged 3 commits into from
Jan 22, 2024

Conversation

MacDue
Copy link
Member

@MacDue MacDue commented Jan 18, 2024

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).

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).
@llvmbot
Copy link
Member

llvmbot commented Jan 18, 2024

@llvm/pr-subscribers-mlir-sve
@llvm/pr-subscribers-mlir-execution-engine
@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-sme

Author: Benjamin Maxwell (MacDue)

Changes

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).


Full diff: https://github.com/llvm/llvm-project/pull/78583.diff

6 Files Affected:

  • (added) mlir/lib/ExecutionEngine/ArmRunnerUtils.cpp (+60)
  • (modified) mlir/lib/ExecutionEngine/CMakeLists.txt (+5)
  • (modified) mlir/test/CMakeLists.txt (+4)
  • (added) mlir/test/Integration/Dialect/Vector/CPU/ArmSME/test-setArmSVLBits.mlir (+76)
  • (added) mlir/test/Integration/Dialect/Vector/CPU/ArmSME/test-setArmVLBits.mlir (+38)
  • (modified) mlir/test/lit.cfg.py (+3)
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.
Copy link
Contributor

@banach-space banach-space left a 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!

Copy link
Collaborator

@c-rhodes c-rhodes left a 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!

Copy link
Collaborator

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?

Copy link
Member Author

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.

@MacDue MacDue merged commit e280c28 into llvm:main Jan 22, 2024
@MacDue MacDue deleted the arm_runner_utils branch January 22, 2024 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants