Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
12ae1ce
feat(sve): sve512_fcmla_arm 全 VL 化 (all-VL Phase 2 P6)
Oct 24, 2026
e5a8473
feat(sve): power_virus_dit_sve_arm 门控迁框架层 (all-VL Phase 2 P6)
Oct 24, 2026
2a4c438
feat(sve): sve512_nt_reload_arm 全 VL 化 (all-VL Phase 2 P6)
Oct 24, 2026
9dab56e
feat(sve): sve512_pred_ops_arm 全 VL 化 (all-VL Phase 2 P6)
Oct 24, 2026
43873e3
feat(sve): sve_fpcr_cartesian_arm 门控迁框架层 (all-VL Phase 2 P6)
Oct 24, 2026
d322906
feat(sve): sve512_stencil_axis_arm 探测迁框架层 (all-VL Phase 2 P6)
Oct 24, 2026
10339ae
feat(sve): sve512_fma_arm 全 VL 化 (all-VL Phase 2 P6)
Oct 24, 2026
6305332
feat(sve2): sve512_fmmla_arm 分流门控迁移 (all-VL Phase 2 P6)
Oct 24, 2026
e91508e
refactor(sve): case getauxval 手探迁移 arm64_require_sve_vl (all-VL P6 批A)
Oct 24, 2026
dd151e1
refactor(sve): kreg getauxval 手探迁移 arm64_require_sve_vl (all-VL P6 批A)
Oct 24, 2026
24a6151
feat(sve2): sve2_cross_precision_arm 分流门控迁移 (all-VL Phase 2 P6)
Oct 24, 2026
1d75c1d
refactor(sve): vector2 getauxval 手探迁移 arm64_require_sve_vl (all-VL P6…
Oct 24, 2026
54aa4ce
refactor(sve): fma getauxval 手探迁移 arm64_require_sve_vl (all-VL P6 批A)
Oct 24, 2026
fb89ae8
feat(sme): sme_za_tileview_arm 门控迁框架层 (all-VL Phase 2 P6)
Oct 24, 2026
736e9f8
feat(sme): sme_fmopa_stress_arm 门控迁框架层 (all-VL Phase 2 P6)
Oct 24, 2026
40a10c8
feat(sve): eigen_svd_bidiag_sve 门控迁框架层 (all-VL Phase 2 P6)
Oct 24, 2026
6aa6250
feat(sve/mesh): mesh_upi_sve 族 auxv 手探迁移框架层 (all-VL Phase 2 P6 批 B)
Oct 24, 2026
608194e
feat(sve/arithmetic): 16 测试 auxv 手探迁移框架层 (all-VL Phase 2 P6 批 B)
Oct 24, 2026
ea59e35
feat(sve/mem): 9 测试 auxv 手探迁移框架层 (all-VL Phase 2 P6 批 B)
Oct 24, 2026
248154d
feat(sve/fma2): 8 测试 auxv 手探迁移框架层 (all-VL Phase 2 P6 批 B)
Oct 24, 2026
2212e3f
docs(build): meson arm64 门控分流注释 P6 终态同步
Oct 24, 2026
ada5ff7
docs(arm64): arm64_vl.h 单位约定审计结论入档 (P6 Task 4)
Oct 24, 2026
154320a
docs(progress): all-VL Phase 2 P6 收官条目 + 战役状态总览
Oct 24, 2026
43301b3
docs(all-vl2): 检视精度两处——vl_bytes 来源注释 + progress-log 库名大小写
Oct 25, 2026
221948a
test(sve): lanes 换算位点补 release 生效 range check ×3——同批迁移标准对齐
Oct 25, 2026
6ceaac9
fix(sve/case): movbe 族 13 文件定容对齐 SVE 上限——消 1024-bit 越界与索引截断 (PR #288 …
Oct 25, 2026
b6695be
fix(sve/kreg): kreg_mask 尾批 asm ldr z 松弛 + aligned_alloc 契约对齐家族 (PR #…
Oct 25, 2026
91886ca
test(sve/kreg): kreg_mask 相位改按子块序号旋转——gt/eq-u/tst 三条谓词路径复活 (PR #288 检…
Oct 25, 2026
312a33d
fix(sve/fpcr): cartesian tie 块操作数/结果迁 vl_w 向量——消任意档位全宽越界 (PR #288 检视 …
Oct 25, 2026
d8c9073
test(sve512): stencil_axis run 侧补 release 生效 VL 漂移守卫——P6 迁移批一致性收口 (PR…
Oct 25, 2026
9e33944
docs(coding): writing_tests.md all-VL 政策返回值措辞修正——EXIT_SKIP 而非 -1 (PR …
Oct 25, 2026
da4435c
fix(sve/case): mrn 家族三文件 spill/phase 缓冲按架构最大 VL 定容 (PR #288 检视 round …
Oct 26, 2026
2637707
test(sve512): fpcr_cartesian 补 init/run VL 漂移守卫——policy #3 一致性收口 (PR …
Oct 26, 2026
2b15e13
fix(sve/mem): mem_disambig_alu 恢复 init 侧 aarch64 守卫——单 TU 自洽性 (PR #28…
Oct 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions docs/coding/writing_tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -646,10 +646,19 @@ instead of assuming one tier:
- **Probe via the framework layer**: `#include
<device/cpu/arm64/arm64_vl.h>` and call
`arm64_require_sve_vl(test, min_bits, max_bits)` /
`arm64_require_sme_svl(...)` from `test_init`; a negative return
(EXIT_SKIP, -255 — the unified require contract) means the helper
already logged the skip — `return EXIT_SKIP` immediately (consume
with `< 0`, never `== -1` / `== EXIT_SKIP`). Do
<<<<<<< HEAD
`arm64_require_sme_svl(...)` from `test_init`; on skip the helper
already logged the reason and returns `EXIT_SKIP` (a negative value,
−255 — the unified require contract, never a bare −1: any other
negative would surface as a misleading "Unexpected OS error") —
`return EXIT_SKIP` immediately (consume with `< 0`, never `== -1`
/ `== EXIT_SKIP`). Do
=======
`arm64_require_sme_svl(...)` from `test_init`; on skip the helper
returns `EXIT_SKIP` (a negative value, −255 — not a bare −1: any other
negative would surface as a misleading "Unexpected OS error") after
logging the reason — `return EXIT_SKIP` immediately. Do
>>>>>>> 52c2d755 (docs(coding): writing_tests.md all-VL 政策返回值措辞修正——EXIT_SKIP 而非 -1 (PR #288 检视 round 2))
not hand-write getauxval probes: `device_has_feature()` is
short-circuited by compile-time `__ARM_FEATURE_*` macros in +sve/+sme
TUs (docs/architecture.md).
Expand Down
51 changes: 41 additions & 10 deletions docs/research/progress-log.md
Original file line number Diff line number Diff line change
Expand Up @@ -714,14 +714,6 @@ M4 未尽项(假通过清单 ARM64 重推导、耗时尾部基线)在 v5 §1
- **验证模式**: 16-run 与 20-commit 实施均由隔离 subagent 执行; 每文件
TU 零告警+skip 干净(框架编译特性门)+终态全量构建零告警+zstd19 pass。
- **诚实边界**: verify.cpp 的 5200 向量 OpenSSL 重验需 SVE 硬件(本机
<<<<<<< HEAD
仅编译验证, commit 正文记录); hmac 容量守卫的 init 侧失败类别已由
20f73730 修正(compute_golden 经返回值传播, test_init 返回
EXIT_FAILURE → 干净 Failed, 非 Skipped)——本条曾按旧形态记账, 评审
二轮勘误同步。
- **承接**:P5(sleef/eigen×8)Eigen 侧已裁自 pin 回退(spike 证据: VLA
语言级不可编译); sleef 半侧待 spike; P6 存量迁移(含本阶段 6 个
遗留手探文件)待做。
## 2026-10-25(PR #280 检视处置 R2:rebase 契约统一 + asm 加固 + FNV 重锚)

- **rebase 到 main(#277 已并入)**:11 条当前 head 意见中 6 条
Expand Down Expand Up @@ -783,19 +775,30 @@ M4 未尽项(假通过清单 ARM64 重推导、耗时尾部基线)在 v5 §1
完整 sdcshield 二进制(fork+96 线程+OpenSSL)不可入 gem5 SE 单进程
配置; 胶水依赖的算术不变式(lanes 换算 svl/4==svcntw()、[4,32]/
[2,16] 范围、漂移比较操作数)已由同源 harness 逐档执行。
=======
仅编译验证, commit 正文记录); hmac 容量守卫的 init 侧失败类别已由
20f73730 修正(compute_golden 经返回值传播, test_init 返回
EXIT_FAILURE → 干净 Failed, 非 Skipped)——本条曾按旧形态记账, 评审
二轮勘误同步。
- **承接**:P5(sleef/eigen×8)Eigen 侧已裁自 pin 回退(spike 证据: VLA
语言级不可编译); sleef 半侧待 spike; P6 存量迁移(含本阶段 6 个
遗留手探文件)待做。
仅编译验证, commit 正文记录); hmac 容量守卫的 init 侧失败经
report_fail_msg 会表现为 Skipped("Unexpected OS error")而非干净
Failed——knob 钳制后不可达, 纯纵深防御, 记账。
- **承接**:P5(sleef/eigen×8)Eigen 侧已裁自 pin 回退(spike 证据: VLA
<<<<<<< HEAD
- **承接**:P5(SLEEF/Eigen×8)Eigen 侧已裁自 pin 回退(spike 证据: VLA
语言级不可编译); sleef 半侧待 spike; P6 存量迁移(含本阶段 6 个
遗留手探文件)待做。
>>>>>>> 853994d3 (docs(all-vl2): P4 收尾——README VL 政策段 all-VL 化 + progress-log 实证条目)
<<<<<<< HEAD
=======
语言级不可编译); P6 存量迁移(含本阶段 6 个遗留手探文件)待做。

<<<<<<< HEAD
## 2026-10-24 · P5 sleef 半侧实证收口(PR #286 检视闭环)
=======
## 2026-10-24(all-VL Phase 2 P5:SLEEF/Eigen×8 按 spike 证据分流——真 VLA 迁移 + 自 pin 回退)
>>>>>>> 51679200 (docs(all-vl2): 检视精度两处——vl_bytes 来源注释 + progress-log 库名大小写)

- **sleef_sve 真 VLA 迁移的 16-run 矩阵全绿**(merge blocker 解除):
gem5-fi `sleef_vla_dual`(feat/sleef-vla-dual @ 6d740525),四档
Expand Down Expand Up @@ -854,3 +857,31 @@ M4 未尽项(假通过清单 ARM64 重推导、耗时尾部基线)在 v5 §1
(CpuNotSupported, 'test compiled with sve');zstd19 -t 2000 -n 1 pass;
x86-64 非回归(纯 aarch64 段内改动)。
>>>>>>> 679c4610 (docs(progress): PR #286 检视 round 1 处置记录——k7pattern tag 32 位拆分 + sve_rot_vla_dual 16-run 实证)
=======

## 2026-10-24(all-VL Phase 2 P6:存量迁移收官——142 文件框架层化 + 分支拓扑修复)

- **迁移成果**(feat/p6-allvl = PR #288, 三批并行代理 + P2 回并, 29+1 commit):
批 A(sve/case 51+kreg 11+vector2 5+fma 10)/批 B(mesh 18+arithmetic 16+
mem 9+fma2 8)/批 C(arm64 13+eigen_bidiag 1+meson 收尾)——全部
getauxval 手探 → arm64_require_sve_vl/sme_svl; 23 个 lanes 文件换算
svl/8|svl/4+范围检查; 全仓活调用审计**仅剩 2 个设计保留**(fmmla/
cross_precision 的 SVE2 HWCAP2 复合门, 测试自有语义)。批 A 净删 279 行。
- **分支拓扑缺陷发现与修复**: P3 当初从 #277 切出漏掉 P2——P3→P4→P5→P6
整条栈缺 P2 的 fmopa_za 重构(批 C 在 P2 之前的旧文件上迁门控被
发现)。修复: P2 并入 P6(20a79b88), fmopa_za 取 P2 版本; 新合并顺序
#277→#283→#284→#286→#280(任意时点)→#288。
- **单位约定审计**(P6 Task 4, ac5b1e6b): 298 调用面统计(~200 纯门控/
97 换算/pin 全字节)——维持现行约定, 教训与防线入档 arm64_vl.h。
- **429 预算中断**: 批 C 代理与 chain 重验代理被 API 预算超限终止;
批 C 收尾由主 agent 补完(dc4b0121); gem5 补证改主 agent 后台自跑。
- **先存缺陷掘出**(记账后续硬化单元, 不混入迁移批): 批 B 报告 7 类
VL>512 越界(vsum[8] 家族/ai[8]/phase[8]/chunk[64]/fsu 跨行/
movmskpspd VL>128 越界读——可移植范式先例 agu_stress_store_only_sve
.cpp:126); 批 A 报告 3 文件 init 取整无 run 守卫; stress 测试
run 侧 assert 在 release(NDEBUG) 失效(P2 时发现)。
- **验证**: 三批各自构建零告警+逐文件/逐 ID skip 核验+grep 归零; 合并
终态 477 测试构建零告警+zstd19 pass; 全仓审计如上。
- **战役状态**: P0-P6 全部落地; PR 编队 #277→#283→#284→#286→#288
(+计划文档 #279/#281/#282/#285/#287)等人工 merge 门。
>>>>>>> a9c1f08c (docs(progress): all-VL Phase 2 P6 收官条目 + 战役状态总览)
10 changes: 10 additions & 0 deletions framework/device/cpu/arm64/arm64_vl.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@
* kernel's clone-inheritance rule (new threads inherit the creator's VL)
* still holds — the framework's thread structure is simply not "test_init
* creates the workers".
*
* UNIT CONVENTION (P6 audit, 2026-10-24 — 298 call sites counted: ~200
* pure gates, 97 lane conversions, all pin sites in bytes): the require
* helpers take the RANGE in BITS (matching how the spec and skip messages
* speak: "128..1024-bit") but RETURN BYTES (what buffers and lanes need);
* the pin helpers take and return BYTES. Lane conversions are therefore
* divisions: f64 lanes = svl/8, f32 lanes = svl/4 (the P2 Critical-1
* lesson — dividing bytes by the wrong power of two compiles silently;
* every conversion site carries a unit comment plus a release-effective
* range check that catches drift).
*/

#include <stdbool.h>
Expand Down
19 changes: 13 additions & 6 deletions tests/cpu/arm64/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,21 @@ if host_machine.cpu_family() == 'aarch64'
# such as this Kunpeng 920. Every test self-gates in test_init and
# returns a clean EXIT_SKIP on SVE-less CPUs, so their SVE
# codegen only ever executes on SVE-capable hardware. Built only on
# aarch64. (Gate split as of all-VL Phase 2: the P3 files gate via
# the framework layer — arm64_require_sve_vl: HWCAP_SVE capability +
# 128..1024-bit range in one call; the remaining legacy files still
# probe HWCAP_SVE by hand and migrate in P6.)
# aarch64. (Gate split as of all-VL Phase 2 P6: every SVE1 test in
# this library gates via the framework layer — arm64_require_sve_vl:
# HWCAP_SVE capability + 128..1024-bit range in one call. The only
# getauxval hand-probes left under tests/cpu/arm64/ are the SVE2
# composite-gate files sve512_fmmla_arm/sve2_cross_precision_arm
# (tests_arm64_sve2 below): their SVE2|F32MM|F64MM / SVE2|SVEBF16
# HWCAP2 conjunctions are the tests' own semantics and stay hand-
# probed by design, while their pure-SVE gate goes through the
# require helper.)
#
# NOTE: sve512_fma_arm.cpp is committed (ea879f68) but deliberately NOT

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[claude] [Minor] 可维护性: 本 PR 重写了 sve512_fma_arm.cpp 的 init 门控、lanes 换算与 run 漂移守卫,但该文件不在任何 sources 列表里,"全量构建零告警" 的验证声明在结构上覆盖不到这个被修改的 TU。
证据: meson.build:156 注释明言 "sve512_fma_arm.cpp is committed (ea879f6) but deliberately NOT wired into any sources list yet",grep 全仓 meson 无第二处引用;而 diff 对 tests/cpu/arm64/sve512_fma_arm.cpp 有实质改动(require 门 + data->vl_d = (size_t)svl / 8 + run 侧 svcntd() != d->vl_d 守卫)——改动只经人工单编(如有)而不过构建,接线前任何语法/头文件回归都不会被 CI 拦截。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[claude] [Minor] 可维护性: d8e6f62 对 sve512_fma_arm.cpp 做了全 VL 化功能改写(require 门控 + lanes 换算 + 漂移守卫),但该文件仍不在任何 sources 列表——PR「全量构建零告警」的验证链根本编译不到它,改写代码零构建验证(腐化风险而非即期错误:本人以同级 build 头文件 -fsyntax-only -march=armv8.2-a+sve 复核通过,EXIT=0)。
证据: 156 行 NOTE "sve512_fma_arm.cpp is committed (ea879f6) but deliberately NOT wired into any sources list";grep -rln sve512_fma_arm.cpp tests/ framework/ 仅命中该注释行;文件 348 行 arm64_require_sve_vl(test,128,1024)、460 行漂移守卫均为本 PR 新代码却无任何 CI 编译覆盖,后续任何 API 演进(如 arm64_vl.h 签名变化)不会在此文件暴露。

# wired into any sources list yet — wiring + all-VL validation is
# scheduled for all-VL Phase 2 P3
# wired into any sources list yet — its source side was migrated to
# the all-VL form in P6 batch C (require + lanes + drift guard, commit
# d8e6f625), so wiring it in only needs the meson entry plus the
# all-VL validation run; the original wiring plan (P3) lapsed unclaimed
# (docs/superpowers/specs/2026-10-23-sve-sme-all-vl2-design.md §6).
arm64_sve_lib = static_library(
'tests_arm64_sve',
Expand Down
28 changes: 15 additions & 13 deletions tests/cpu/arm64/power_virus_dit_sve_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@
* enhancement, not a requirement — the NEON version ships the same
* way).
*
* test_init probes HWCAP_SVE and returns a clean EXIT_SKIP on SVE-less
* CPUs. Any runtime vector length (full 512-bit on 0xd22). Built in
* test_init gates via the framework layer (arm64_require_sve_vl:
* HWCAP_SVE capability + 128..1024-bit range in one call, all-VL
* Phase 2 P6) and returns a clean EXIT_SKIP on SVE-less CPUs. The run
* side reads the VL fresh (svcntd) and derives the golden from the
* same lanes, so no init/run VL state exists to drift. Built in
* tests_arm64_sve.
* @endparblock
*/
Expand All @@ -51,9 +54,8 @@
#include <vector>

#ifdef __aarch64__
#include <sys/auxv.h>
#include <asm/hwcap.h>
#include <arm_sve.h>
#include <device/cpu/arm64/arm64_vl.h>
#endif

// Burst/stall sizes (matched duty cycle, power_virus_dit precedent).
Expand All @@ -74,14 +76,14 @@ static constexpr double B1 = -0.8333333333333333; // 0xBFEAAAAAAAAAAAAA

static int power_virus_dit_sve_arm_init(struct test *test)
{
unsigned long hwcap = getauxval(AT_HWCAP);
if ((hwcap & HWCAP_SVE) == 0) {
log_skip(CpuNotSupportedSkipCategory,
"ARM64 SVE not available; power_virus_dit_sve_arm "
"requires SVE (full-width di/dt burst)");
/* All-VL Phase 2 P6: capability + 128..1024-bit range check in one
framework-layer call, replacing the getauxval hand-probe. Gate
only: the run side re-reads svcntd() and sizes its buffers and
golden from the same lanes (no init/run VL state to drift). */
const long svl = arm64_require_sve_vl(test, 128, 1024);
if (svl < 0)
return EXIT_SKIP;
}
(void)test;
(void)svl;
return EXIT_SUCCESS;
}

Expand Down Expand Up @@ -214,8 +216,8 @@ DECLARE_TEST(power_virus_dit_sve_arm,
"svmla_f64_x burst chains with alternating high-Hamming "
"operands and periodic stack-reload SVE loads (address "
"generation inside the burst window), alternating with yield "
"stalls — the SVE-512 port of power_virus_dit, byte-exact vs "
"a per-lane scalar fma golden")
"stalls — the full-width SVE port of power_virus_dit, "
"byte-exact vs a per-lane scalar fma golden")
.groups = DECLARE_TEST_GROUPS(&group_math),
.test_init = power_virus_dit_sve_arm_init,
.test_run = power_virus_dit_sve_arm_run,
Expand Down
51 changes: 28 additions & 23 deletions tests/cpu/arm64/sme_fmopa_stress_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@
* - all-core concurrency: 608 threads each in their own streaming
* window (per-thread ZA, no sharing).
*
* Gates: HWCAP2 SME bit, then a runtime rdsvl check bounding SVL to the
* supported 128..1024-bit range (n = SVL/4 f32 lanes per slice; the
* geometry was characterized at 512-bit on cn23154 and the parameterized
* asm verified at all four SVLs in gem5). Non-aarch64 hosts, non-clang
* compilers, and out-of-range SVLs skip with an honest reason. x86-64
* untouched.
* Gates: the framework layer's arm64_require_sme_svl (HWCAP2_SME
* capability + 128..1024-bit SVL range in one call, all-VL Phase 2
* P6), then the characterized-geometry guard (n = SVL/4 f32 lanes per
* slice within [4, kTileNMax]; the geometry was characterized at
* 512-bit on cn23154 and the parameterized asm verified at all four
* SVLs in gem5). Non-aarch64 hosts, non-clang compilers, and
* out-of-range SVLs skip with an honest reason; test_run re-checks the
* SVL and fails closed on drift. x86-64 untouched.
* @endparblock
*/

Expand All @@ -56,12 +58,7 @@
#include <vector>

#ifdef __aarch64__
#include <sys/auxv.h>
#include <asm/hwcap.h>
#endif
/* Kernel headers of the SME era define this; older ones (5.10) do not. */
#ifndef HWCAP2_SME
#define HWCAP2_SME (1UL << 23)
#include <device/cpu/arm64/arm64_vl.h>
#endif

/* Full-SVL support (128..1024-bit): n = SVL/4 f32 lanes per slice is
Expand Down Expand Up @@ -163,18 +160,16 @@ static int sme_fmopa_stress_arm_init(struct test *test)
"built with clang on aarch64 (armv9-a+sve+sme+sme-f64f64)");
return EXIT_SKIP;
#else
unsigned long hwcap2 = getauxval(AT_HWCAP2);
if ((hwcap2 & HWCAP2_SME) == 0) {
log_skip(CpuNotSupportedSkipCategory,
"ARM64 SME not available; sme_fmopa_stress_arm exercises "
"the FMOPA matrix-accumulate datapath");
/* All-VL Phase 2 P6: HWCAP2_SME capability + 128..1024-bit SVL range
* in one framework-layer call, replacing the getauxval hand-probe and
* the inline rdsvl (the helper reads rdsvl #1 internally — SME
* implies SVE, so it cannot SIGILL here). Returns the SVL in BYTES;
* the n = SVL/4 geometry and the [4, kTileNMax] stack-buffer guard
* below are the gem5-verified parameterized geometry and stay
* untouched. */
const long svl_bytes = arm64_require_sme_svl(test, 128, 1024);
if (svl_bytes < 0)
return EXIT_SKIP;
}

/* RDVL Xd, #imm = VL_bytes * imm; #1 reads the streaming vector
* length in bytes. SME implies SVE, so rdsvl cannot SIGILL here. */
long svl_bytes;
asm volatile("rdsvl %0, #1" : "=r"(svl_bytes));
const long n = svl_bytes / 4;
if (n < 4 || n > kTileNMax) {
log_skip(CpuNotSupportedSkipCategory,
Expand Down Expand Up @@ -246,6 +241,16 @@ static int sme_fmopa_stress_arm_run(struct test *test, int cpu)
* pin init's invariant (n within [4, kTileNMax]) before any buffer
* math (PR #242 review, coderabbit). */
assert(n >= 4 && n <= kTileNMax);
/* All-VL policy #3: fail closed on init/run SVL drift — the shared
* golden is sized at init's n, and the assert above only pins the
* stored invariant (NDEBUG-sensitive); this check is
* release-effective and compares a fresh rdsvl read. */
if (arm64_sme_svl_bytes() / 4 != n) {
log_error("sme_fmopa_stress_arm: SVL drifted between init (n=%ld) "
"and run (n=%ld)", n, arm64_sme_svl_bytes() / 4);
report_fail_msg("sme_fmopa_stress_arm: SME SVL drifted between "
"init and run");
}
const size_t count = static_cast<size_t>(n) * n;
const size_t bytes = count * sizeof(float);

Expand Down
47 changes: 26 additions & 21 deletions tests/cpu/arm64/sme_za_tileview_arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@
* ZA stores, register-offset addressing) are spelled out so codegen
* cannot drift from the measured recipe.
*
* Gates: HWCAP2 SME bit, then a runtime rdsvl check pinning the
* characterized geometry (8 f64 per slice). Non-aarch64 hosts, non-
* clang compilers, and uncharacterized SVLs skip with an honest reason.
* Gates: the framework layer's arm64_require_sme_svl (HWCAP2_SME
* capability + 128..1024-bit SVL range in one call, all-VL Phase 2
* P6), then the characterized-geometry guard (n = SVL/8 f64 per slice
* within [2, kTileNMax]). Non-aarch64 hosts, non-clang compilers, and
* uncharacterized SVLs skip with an honest reason. test_run re-checks
* the SVL and fails closed on drift.
* @endparblock
*/

Expand All @@ -60,13 +63,7 @@
#include <vector>

#ifdef __aarch64__
#include <sys/auxv.h>
#include <asm/hwcap.h>
#endif

/* Kernel headers of the SME era define this; older ones (5.10) do not. */
#ifndef HWCAP2_SME
#define HWCAP2_SME (1UL << 23)
#include <device/cpu/arm64/arm64_vl.h>
#endif

/* Full-SVL support (128..1024-bit): n = SVL/8 f64 per ZA slice is read
Expand Down Expand Up @@ -197,18 +194,16 @@ static int sme_za_tileview_arm_init(struct test *test)
"built with clang on aarch64 (armv9-a+sve+sme+sme-f64f64)");
return EXIT_SKIP;
#else
unsigned long hwcap2 = getauxval(AT_HWCAP2);
if ((hwcap2 & HWCAP2_SME) == 0) {
log_skip(CpuNotSupportedSkipCategory,
"ARM64 SME not available; sme_za_tileview_arm exercises "
"the ZA tile-view datapath");
/* All-VL Phase 2 P6: HWCAP2_SME capability + 128..1024-bit SVL range
* in one framework-layer call, replacing the getauxval hand-probe and
* the inline rdsvl (the helper reads rdsvl #1 internally — SME
* implies SVE, so it cannot SIGILL here). Returns the SVL in BYTES;
* the n = SVL/8 geometry and the [2, kTileNMax] stack-buffer guard
* below are the P1-242/PR-#242-verified parameterized geometry and
* stay untouched. */
const long svl_bytes = arm64_require_sme_svl(test, 128, 1024);
if (svl_bytes < 0)
return EXIT_SKIP;
}

/* RDVL Xd, #imm = VL_bytes * imm, so #1 reads the streaming vector
* length in bytes. SME implies SVE, so rdsvl cannot SIGILL here. */
long svl_bytes;
asm volatile("rdsvl %0, #1" : "=r"(svl_bytes));
const long n = svl_bytes / 8;
if (n < 2 || n > kTileNMax) {
log_skip(CpuNotSupportedSkipCategory,
Expand Down Expand Up @@ -302,6 +297,16 @@ static int sme_za_tileview_arm_run(struct test *test, int cpu)
* so pin init's invariant (n within [2, kTileNMax]) before any buffer
* math (PR #242 review, coderabbit). */
assert(n >= 2 && n <= kTileNMax);
/* All-VL policy #3: fail closed on init/run SVL drift — the shared
* goldens are sized at init's n, and the assert above only pins the
* stored invariant (NDEBUG-sensitive); this check is
* release-effective and compares a fresh rdsvl read. */
if (arm64_sme_svl_bytes() / 8 != n) {
log_error("sme_za_tileview_arm: SVL drifted between init (n=%ld) "
"and run (n=%ld)", n, arm64_sme_svl_bytes() / 8);
report_fail_msg("sme_za_tileview_arm: SME SVL drifted between "
"init and run");
}
const size_t count = static_cast<size_t>(n) * n;
const size_t bytes = count * sizeof(double);

Expand Down
Loading
Loading