To run integration tests using qemu-aarch64 on x64 host, below flags are
added to the cmake command when building mlir/llvm:
-DMLIR_INCLUDE_INTEGRATION_TESTS=ON \
-DMLIR_RUN_ARM_SVE_TESTS=ON \
-DMLIR_RUN_ARM_SME_TESTS=ON \
-DARM_EMULATOR_EXECUTABLE="<...>/qemu-aarch64" \
-DARM_EMULATOR_OPTIONS="-L /usr/aarch64-linux-gnu" \
-DARM_EMULATOR_MLIR_CPU_RUNNER_EXECUTABLE="<llvm_arm64_build_top>/bin/mlir-cpu-runner-arm64"
\
-DARM_EMULATOR_LLI_EXECUTABLE="<llvm_arm64_build_top>/bin/lli" \
-DARM_EMULATOR_UTILS_LIB_DIR="<llvm_arm64_build_top>/lib"
The last three above are prebuilt on, or cross-built for, an aarch64
host.
This patch introduced substittutions of "%native_mlir_runner_utils" etc. and use
them in SVE/SME integration tests. When configured to run using qemu-aarch64,
mlir runtime util libs will be loaded from ARM_EMULATOR_UTILS_LIB_DIR, if set.
Some tests marked with 'UNSUPPORTED: target=aarch64{{.*}}' are still run
when configured with ARM_EMULATOR_EXECUTABLE and the default target is
not aarch64.
A lit config feature 'mlir_arm_emulator' is added in
mlir/test/lit.site.cfg.py.in and to UNSUPPORTED list of such tests.
75 lines
2.3 KiB
MLIR
75 lines
2.3 KiB
MLIR
// DEFINE: %{entry_point} = entry
|
|
// DEFINE: %{compile} = mlir-opt %s -test-lower-to-arm-sme -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=%native_mlir_runner_utils,%native_mlir_c_runner_utils,%native_arm_sme_abi_shlib
|
|
|
|
// RUN: %{compile} | %{run} | FileCheck %s
|
|
|
|
func.func @entry() {
|
|
%c0 = arith.constant 0 : index
|
|
%c1 = arith.constant 1 : index
|
|
%c1_i32 = arith.constant 1 : i32
|
|
|
|
// Calculate the size of a 32-bit tile, e.g. ZA{n}.s.
|
|
%svl_s = arm_sme.streaming_vl <word>
|
|
%za_s_size = arith.muli %svl_s, %svl_s : index
|
|
|
|
// Allocate memory.
|
|
%mem1 = memref.alloca(%za_s_size) : memref<?xi32>
|
|
|
|
// Fill each "row" of "mem1" with row number.
|
|
//
|
|
// For example, assuming an SVL of 128-bits:
|
|
//
|
|
// 0, 0, 0, 0
|
|
// 1, 1, 1, 1
|
|
// 2, 2, 2, 2
|
|
// 3, 3, 3, 3
|
|
//
|
|
%init_0 = arith.constant 0 : i32
|
|
scf.for %i = %c0 to %za_s_size step %svl_s iter_args(%val = %init_0) -> (i32) {
|
|
%splat_val = vector.broadcast %val : i32 to vector<[4]xi32>
|
|
vector.store %splat_val, %mem1[%i] : memref<?xi32>, vector<[4]xi32>
|
|
%val_next = arith.addi %val, %c1_i32 : i32
|
|
scf.yield %val_next : i32
|
|
}
|
|
|
|
// Load tile from "mem1" vertically.
|
|
%0 = arm_sme.tile_load %mem1[%c0, %c0] layout<vertical> : memref<?xi32>, vector<[4]x[4]xi32>
|
|
|
|
// 1. ORIGINAL HORIZONTAL LAYOUT
|
|
// Dump "mem1". The smallest SVL is 128-bits so the tile will be at least
|
|
// 4x4xi32.
|
|
//
|
|
// CHECK: TILE BEGIN
|
|
// CHECK-NEXT: ( 0, 0, 0, 0
|
|
// CHECK-NEXT: ( 1, 1, 1, 1
|
|
// CHECK-NEXT: ( 2, 2, 2, 2
|
|
// CHECK-NEXT: ( 3, 3, 3, 3
|
|
// CHECK: TILE END
|
|
vector.print str "TILE BEGIN\n"
|
|
scf.for %i = %c0 to %za_s_size step %svl_s {
|
|
%tileslice = vector.load %mem1[%i] : memref<?xi32>, vector<[4]xi32>
|
|
vector.print %tileslice : vector<[4]xi32>
|
|
}
|
|
vector.print str "TILE END\n"
|
|
|
|
// 2. VERTICAL LAYOUT
|
|
// Dump "mem2". The smallest SVL is 128-bits so the tile will be at least
|
|
// 4x4xi32.
|
|
//
|
|
// CHECK: TILE BEGIN
|
|
// CHECK-NEXT: ( 0, 1, 2, 3
|
|
// CHECK-NEXT: ( 0, 1, 2, 3
|
|
// CHECK-NEXT: ( 0, 1, 2, 3
|
|
// CHECK-NEXT: ( 0, 1, 2, 3
|
|
// CHECK: TILE END
|
|
vector.print str "TILE BEGIN\n"
|
|
vector.print %0 : vector<[4]x[4]xi32>
|
|
vector.print str "TILE END\n"
|
|
|
|
return
|
|
}
|