Skip to content

Commit e280c28

Browse files
authored
[mlir] Add mlir_arm_runner_utils library for use in integration tests (#78583)
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).
1 parent 9f7fff7 commit e280c28

File tree

8 files changed

+220
-0
lines changed

8 files changed

+220
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//===- ArmRunnerUtils.cpp - Utilities for configuring architecture properties //
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/Support/MathExtras.h"
10+
#include <iostream>
11+
#include <stdint.h>
12+
#include <string_view>
13+
14+
#if (defined(_WIN32) || defined(__CYGWIN__))
15+
#define MLIR_ARMRUNNERUTILS_EXPORTED __declspec(dllexport)
16+
#else
17+
#define MLIR_ARMRUNNERUTILS_EXPORTED __attribute__((visibility("default")))
18+
#endif
19+
20+
#ifdef __linux__
21+
#include <sys/prctl.h>
22+
#endif
23+
24+
extern "C" {
25+
26+
// Defines for prctl() calls. These may not necessarily exist in the host
27+
// <sys/prctl.h>, but will still be useable under emulation.
28+
//
29+
// https://www.kernel.org/doc/html/v5.3/arm64/sve.html#prctl-extensions
30+
#ifndef PR_SVE_SET_VL
31+
#define PR_SVE_SET_VL 50
32+
#endif
33+
// https://docs.kernel.org/arch/arm64/sme.html#prctl-extensions
34+
#ifndef PR_SME_SET_VL
35+
#define PR_SME_SET_VL 63
36+
#endif
37+
// Note: This mask is the same as both PR_SME_VL_LEN_MASK and
38+
// PR_SVE_VL_LEN_MASK.
39+
#define PR_VL_LEN_MASK 0xffff
40+
41+
static void setArmVectorLength(std::string_view helper_name, int option,
42+
uint32_t bits) {
43+
#if defined(__linux__) && defined(__aarch64__)
44+
if (bits < 128 || bits > 2048 || !llvm::isPowerOf2_32(bits)) {
45+
std::cerr << "[error] Attempted to set an invalid vector length (" << bits
46+
<< "-bit)" << std::endl;
47+
abort();
48+
}
49+
uint32_t vl = bits / 8;
50+
if (auto ret = prctl(option, vl & PR_VL_LEN_MASK); ret < 0) {
51+
std::cerr << "[error] prctl failed (" << ret << ")" << std::endl;
52+
abort();
53+
}
54+
#else
55+
std::cerr << "[error] " << helper_name << " is unsupported" << std::endl;
56+
abort();
57+
#endif
58+
}
59+
60+
/// Sets the SVE vector length (in bits) to `bits`.
61+
void MLIR_ARMRUNNERUTILS_EXPORTED setArmVLBits(uint32_t bits) {
62+
setArmVectorLength(__func__, PR_SVE_SET_VL, bits);
63+
}
64+
65+
/// Sets the SME streaming vector length (in bits) to `bits`.
66+
void MLIR_ARMRUNNERUTILS_EXPORTED setArmSVLBits(uint32_t bits) {
67+
setArmVectorLength(__func__, PR_SME_SET_VL, bits);
68+
}
69+
}

mlir/lib/ExecutionEngine/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# is a big dependency which most don't need.
33

44
set(LLVM_OPTIONAL_SOURCES
5+
ArmRunnerUtils.cpp
56
ArmSMEStubs.cpp
67
AsyncRuntime.cpp
78
CRunnerUtils.cpp
@@ -186,6 +187,10 @@ if(LLVM_ENABLE_PIC)
186187
ArmSMEStubs.cpp)
187188
target_compile_definitions(mlir_arm_sme_abi_stubs PRIVATE mlir_arm_sme_abi_stubs_EXPORTS)
188189

190+
add_mlir_library(mlir_arm_runner_utils
191+
SHARED
192+
ArmRunnerUtils.cpp)
193+
189194
if(MLIR_ENABLE_CUDA_RUNNER)
190195
# Configure CUDA support. Using check_language first allows us to give a
191196
# custom error message.

mlir/test/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ if (MLIR_RUN_ARM_SME_TESTS AND NOT ARM_SME_ABI_ROUTINES_SHLIB)
153153
list(APPEND MLIR_TEST_DEPENDS mlir_arm_sme_abi_stubs)
154154
endif()
155155

156+
if (MLIR_RUN_ARM_SVE_TESTS OR MLIR_RUN_ARM_SME_TESTS)
157+
list(APPEND MLIR_TEST_DEPENDS mlir_arm_runner_utils)
158+
endif()
159+
156160
list(APPEND MLIR_TEST_DEPENDS MLIRUnitTests)
157161

158162
if(LLVM_BUILD_EXAMPLES)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# The tests in this folder assume full control of the hardware features, such as
2+
# the vector length, so must be run under an emulator.
3+
4+
if not config.arm_emulator_executable:
5+
config.unsupported = True
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// DEFINE: %{entry_point} = main
2+
// DEFINE: %{compile} = mlir-opt %s -convert-arm-sme-to-llvm -test-lower-to-llvm
3+
// DEFINE: %{run} = %mcr_aarch64_cmd \
4+
// DEFINE: -march=aarch64 -mattr=+sve,+sme \
5+
// DEFINE: -e %{entry_point} -entry-point-result=void \
6+
// DEFINE: -shared-libs=%mlir_runner_utils,%mlir_c_runner_utils,%mlir_arm_runner_utils
7+
8+
// RUN: %{compile} | %{run} | FileCheck %s
9+
10+
func.func @checkSVL() {
11+
%svl_b = arm_sme.streaming_vl <byte>
12+
%svl_h = arm_sme.streaming_vl <half>
13+
%svl_w = arm_sme.streaming_vl <word>
14+
%svl_d = arm_sme.streaming_vl <double>
15+
vector.print str "SVL.b"
16+
vector.print %svl_b : index
17+
vector.print str "SVL.h"
18+
vector.print %svl_h : index
19+
vector.print str "SVL.w"
20+
vector.print %svl_w : index
21+
vector.print str "SVL.d"
22+
vector.print %svl_d : index
23+
return
24+
}
25+
26+
func.func @setAndCheckSVL(%bits: i32) {
27+
func.call @setArmSVLBits(%bits) : (i32) -> ()
28+
func.call @checkSVL() : () -> ()
29+
return
30+
}
31+
32+
func.func @main() {
33+
// CHECK: SVL.b
34+
// CHECK-NEXT: 16
35+
//
36+
// CHECK-NEXT: SVL.h
37+
// CHECK-NEXT: 8
38+
//
39+
// CHECK-NEXT: SVL.w
40+
// CHECK-NEXT: 4
41+
//
42+
// CHECK-NEXT: SVL.d
43+
// CHECK-NEXT: 2
44+
%c128 = arith.constant 128 : i32
45+
func.call @setAndCheckSVL(%c128) : (i32) -> ()
46+
47+
// CHECK: SVL.b
48+
// CHECK-NEXT: 32
49+
//
50+
// CHECK-NEXT: SVL.h
51+
// CHECK-NEXT: 16
52+
//
53+
// CHECK-NEXT: SVL.w
54+
// CHECK-NEXT: 8
55+
//
56+
// CHECK-NEXT: SVL.d
57+
// CHECK-NEXT: 4
58+
%c256 = arith.constant 256 : i32
59+
func.call @setAndCheckSVL(%c256) : (i32) -> ()
60+
61+
// CHECK: SVL.b
62+
// CHECK-NEXT: 64
63+
//
64+
// CHECK-NEXT: SVL.h
65+
// CHECK-NEXT: 32
66+
//
67+
// CHECK-NEXT: SVL.w
68+
// CHECK-NEXT: 16
69+
//
70+
// CHECK-NEXT: SVL.d
71+
// CHECK-NEXT: 8
72+
%c512 = arith.constant 512 : i32
73+
func.call @setAndCheckSVL(%c512) : (i32) -> ()
74+
75+
return
76+
}
77+
78+
func.func private @setArmSVLBits(%bits : i32)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# The tests in this folder assume full control of the hardware features, such as
2+
# the vector length, so must be run under an emulator.
3+
4+
if not config.arm_emulator_executable:
5+
config.unsupported = True
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// DEFINE: %{entry_point} = main
2+
// DEFINE: %{compile} = mlir-opt %s -test-lower-to-llvm
3+
// DEFINE: %{run} = %mcr_aarch64_cmd -march=aarch64 -mattr=+sve \
4+
// DEFINE: -e %{entry_point} -entry-point-result=void \
5+
// DEFINE: -shared-libs=%mlir_runner_utils,%mlir_c_runner_utils,%mlir_arm_runner_utils
6+
7+
// RUN: %{compile} | %{run} | FileCheck %s
8+
9+
func.func @checkVScale() {
10+
%vscale = vector.vscale
11+
vector.print str "vscale"
12+
vector.print %vscale : index
13+
return
14+
}
15+
16+
func.func @setAndCheckVL(%bits: i32) {
17+
func.call @setArmVLBits(%bits) : (i32) -> ()
18+
func.call @checkVScale() : () -> ()
19+
return
20+
}
21+
22+
func.func @main() {
23+
// CHECK: vscale
24+
// CHECK-NEXT: 1
25+
%c128 = arith.constant 128 : i32
26+
func.call @setAndCheckVL(%c128) : (i32) -> ()
27+
28+
// CHECK: vscale
29+
// CHECK-NEXT: 2
30+
%c256 = arith.constant 256 : i32
31+
func.call @setAndCheckVL(%c256) : (i32) -> ()
32+
33+
// CHECK: vscale
34+
// CHECK-NEXT: 4
35+
%c512 = arith.constant 512 : i32
36+
func.call @setAndCheckVL(%c512) : (i32) -> ()
37+
38+
// CHECK: vscale
39+
// CHECK-NEXT: 8
40+
%c1024 = arith.constant 1024 : i32
41+
func.call @setAndCheckVL(%c1024) : (i32) -> ()
42+
43+
// CHECK: vscale
44+
// CHECK-NEXT: 16
45+
%c2048 = arith.constant 2048 : i32
46+
func.call @setAndCheckVL(%c2048) : (i32) -> ()
47+
48+
return
49+
}
50+
51+
func.func private @setArmVLBits(%bits : i32)

mlir/test/lit.cfg.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ def add_runtime(name):
135135
if config.enable_sycl_runner:
136136
tools.extend([add_runtime("mlir_sycl_runtime")])
137137

138+
if config.mlir_run_arm_sve_tests or config.mlir_run_arm_sme_tests:
139+
tools.extend([add_runtime("mlir_arm_runner_utils")])
140+
138141
if config.mlir_run_arm_sme_tests:
139142
config.substitutions.append(
140143
(

0 commit comments

Comments
 (0)