# aurasuisui/rvv v0.1.0 计划

> **目标**:在 MoonBit 库层提供 5 个数组原语的 RVV 实现路径,并在无 RISC-V 硬件的条件下可复现验证。
> **非目标**:不改 MoonBit 编译器、不做 RVV 汇编器/反汇编器、不做浮点原语、不做运行时 CPU 探测、不做手写汇编内核。
> **时点**:基线取证 2026-11-13;仓库以 `main` 首个提交为基线。

| 项 | 值 |
|---|---|
| 包名 | `aurasuisui/rvv` |
| 版本 | `0.1.0`(首次发布) |
| 版本判定 | **MINOR**(0.x 首个公开版本;不是 PATCH,未到 MAJOR) |
| 仓库 | `Desktop\\moonbit-dev\\moonbit-rvv` |
| 许可证 | Apache-2.0 |
| 工具链 | moon 0.1.20261104 / clang 19.1.7 / riscv64-linux-gnu-gcc 11.4.0 |
| 依据 | `Desktop\\moonbit-dev\\rvv-brief.md`(F1–F12 已独立复核;F13 待 M0 复核) |
| 分支模型 | `main` 只收初始化、里程碑合并、发布提交;工作分支 `milestone/Mx-<slug>` |
| 状态 | M0–M3 已交付;M4 T0–T3 通过、T4 待人类(发布门禁)。lead 自审 + plan-lint 0/0,非独立复核 |
| 稿次 | 第 3 稿(加入文档体系、Git 模型、源码分包、看板、基线) |

## 0. 一页读懂

**做什么**:一套 5 原语的数组 API,wasm/js 走纯 MoonBit 标量,native 走 C 标量,RISC-V 走 RVV;同一份公开签名,按目标选实现。

**交付物**:可用 `moon add` 引入的包 + 可复现的 5×3×3 基准表 + 交叉编译到 RV64 的脚本与配方。

**成功标准**:

1. 干净目录 `moon add aurasuisui/rvv@0.1.0` 后,wasm-gc 与 native 都跑出正确结果。
2. 交叉编译到 RV64 的产物在 qemu 上走 RVV 分支,结果与标量逐元素相等。
3. 5 个原语的基准表可一条命令复现,数字标口径。
4. README 里的交叉编译配方可被第三方照着复现第 2 条。

**周期**:16 个工作日(建议 11/14 起,12/05 发布,含 3 天缓冲)。

## 一、依据与事实

| 编号 | 事实 | 状态 |
|---|---|---|
| F1 | MoonBit 无内联汇编、无 RVV intrinsics;`asm` 是保留字 | ✅ |
| F2 | 包可带 C:`native-stub` | ✅ |
| F3 | `moonbit_simd.h` 只有 NEON/SSE2,`riscv` 提及 0 次 | ✅ |
| F4 | 官方目标无 riscv64;LLVM 后端在本工具链不可用 | ✅ |
| F5 | native→C→RV64 可行;宿主不落 `.c`;`MOON_CC` 需带 `ar`;需 sysroot 或 `-static` | ✅ 已修正 |
| F6 | 官方工具链只有 x86_64/aarch64 | ✅ |
| F7 | RVA23 把 V 列为必选;Android ABI 以 RVA23 为基线 | ✅ |
| F8 | RVV 汇编受 binutils 版本限制(2.35 不行,2.38 可以) | ⚠️ 已限定 |
| F9 | QEMU 6.2 无 V,8.2 有 | ✅ |
| F10 | QEMU 计数器不可信(0.2~40% 波动,1.6~24× 虚高) | ❌ 量化已修正 |
| F11 | spike 需 `zicntr`,指令数确定性 | ✅ |
| F12 | 首轮 9 个数字逐位可复现(N=8192、REPS=4、VLEN=128) | ✅ |
| F13 | `targets` 可把 `extern "C"` 与 wasm-gc 隔离(上一会话报告) | ⚠️ 待 M0 复核 |

## 二、基线

| 项 | 实测值 | 复核方式 |
|---|---|---|
| 仓库 | 初始化前只有 `docs/plans/v0.1.0.md` | `git rev-parse --is-inside-work-tree`(初始化后为 true) |
| 工作树 | 本计划所在提交 | `git log -1 --oneline` |
| moon | 0.1.20261104 (940aa18 2026-11-04) | `moon version` |
| 目标 | `moon build --target` = wasm / wasm-gc / js / native / llvm / all | `moon build --help` |
| clang | 19.1.7 | `clang-19 --version` |
| 裸机 gcc | 10.2.0,binutils 2.35.1 | `riscv64-unknown-elf-gcc --version` |
| Linux 交叉 gcc | 11.4.0 | `riscv64-linux-gnu-gcc --version` |
| QEMU | 8.2.2(`~/qemu82`);系统 6.2.0 | `~/qemu82/bin/qemu-system-riscv64 --version` |
| spike | 1.1.1-dev | `~/spike/bin/spike --help` |
| 构建/测试 | N/A(尚无代码) | M0 出口条件中的命令,结果回填此处 |
| 首轮基准 | 9 个指令数(附录 A) | `research/rvv-bench/build_spike.sh` + spike 复跑 |

## 三、范围

### 3.1 API(5 个原语)

| API | 语义 | 边界 |
|---|---|---|
| `sum(xs) -> Int64` | 求和,中间值 Int64 | 空数组返回 0 |
| `count_ge(xs, thr) -> Int` | 统计 >= thr 的元素数 | 空数组返回 0 |
| `prefix_sum(xs) -> Unit` | 原地前缀和,按 32 位回绕 | 空数组无操作 |
| `filter(xs, thr) -> FixedArray[Int]` | 取出 >= thr 的元素,保持原序 | 无匹配返回空数组 |
| `dot(a, b) -> Int64` | 点积,中间值 Int64 | 长度不等 panic(`rvv: dot length mismatch`) |

### 3.2 三层实现

| 层 | 文件 | 何时生效 |
|---|---|---|
| MoonBit 标量 | `src/scalar/impl.mbt` | wasm / wasm-gc / js |
| C(标量 + RVV) | `src/native/kernel.c`(`native-stub`) | native |
| 分派 | `src/lib.mbt` + 两个 target 文件 | 全后端,只做参数检查与转发 |

`kernel.c` 用编译期开关,不做运行时探测:

```c
#include <moonbit.h>
#if defined(__riscv_vector)
#include <riscv_vector.h>
#define RVV 1
#endif
```

### 3.3 源码结构(不堆平)

```
src/
├── moon.pkg                # 公开包 aurasuisui/rvv;native-stub + 文件级 targets
├── lib.mbt                 # 公开 API(M0 探针;M1 起 5 原语)
├── dispatch_wasm.mbt       # targets: wasm, wasm-gc, js → 标量
├── dispatch_native.mbt     # targets: native → extern "C"
├── scalar/                 # M1 起:纯 MoonBit 标量实现(可无条件导入)
│   ├── moon.pkg
│   └── impl.mbt
├── native/
│   └── kernel.c            # 只是 C 文件,由 native-stub 引用(不是包)
├── tests/                  # M1 起:黑盒测试
│   ├── moon.pkg
│   └── api_test.mbt
└── probe/                  # M0 可执行探针(M4 决定保留为 example 或删除)
    ├── moon.pkg
    └── main.mbt
scripts/
├── cross-riscv.sh          # cc/ar wrapper + 交叉编译
├── run-qemu.sh
└── bench.sh
bench/                      # 裸机 C harness(无 moon.pkg,不参与包构建)
.github/workflows/ci.yml    # 仅 wasm/native 主机门禁
```

**结构结论(M0 已采用回退)**:`for "native"` 条件包导入在本工具链不被支持(解析错误);给 native 子包加 `supported_targets` 后,wasm-gc 构建会报依赖图不兼容。因此 v0.1.0 用**单包 + 文件级 `targets`**(F13 模式):`kernel.c` 放 `src/native/` 由 `native-stub` 引用;纯标量实现与黑盒测试在 M1 以可无条件导入的子包加入(`src/scalar/`、`src/tests/`)。

### 3.4 文档体系(对齐 bimap,严格 SSOT)

| 文档 | 角色 | 产生时点 |
|---|---|---|
| `README.md` | 产品门面:用途、安装、API 表、配方入口、性能口径 | 初始化骨架,M4 定稿 |
| `CONTRIBUTING.md` | 开发圣经:布局、分支/提交、测试、**文档同步约定** | 初始化 |
| `AGENTS.md` | agent 入口:命令、结构、文档地图、硬规矩 | 初始化 |
| `CHANGELOG.md` | 变更史 + 偏离记录 | 初始化 |
| `docs/README.md` | **文档枢纽 + 全量地图 + SSOT 表** | 初始化 |
| `docs/SPEC.md` | API 唯一真源:签名、语义、边界、panic、回绕 | M1 |
| `docs/NATIVE_ABI.md` | MoonBit↔C ABI:Int= int32、数组布局、所有权 | M2 |
| `docs/CROSS_COMPILE.md` | RV64 交叉配方(核心资产) | M2 |
| `docs/BENCHMARKS.md` | 口径、方法、结果、限制 | M3 |
| `docs/RELEASE_CHECKLIST.md` | 发布门禁 | M4 |
| `docs/plans/v0.1.0.md` | 本计划 | 现在 |

**SSOT 纪律**:每条事实只住一个文件,别处只链接。API 语义→SPEC;用法→README;交叉→CROSS_COMPILE;ABI→NATIVE_ABI;数字→BENCHMARKS;发布→RELEASE_CHECKLIST;开发规则→CONTRIBUTING;变更→CHANGELOG。新增/删除文档必须同步 `docs/README.md`。

### 3.5 Git 分支与提交模型

- `main` 只允许三类提交:① 初始化;② 每个里程碑的 `--no-ff` 合并;③ 发布提交/标签。
- 所有功能改动在 `milestone/Mx-<slug>` 分支进行;子智能体只在该分支提交。
- 每个里程碑最多 3 个逻辑提交;WIP 在合并前 squash,禁止"改错字"式碎片链。
- 合并前必须由 lead 独立复跑验收;合并用 `git merge --no-ff`。
- 不 push、不打 tag、不发布,除非人类明确口令。

### 3.6 版本判定

`0.1.0` 是首个公开版本,按 SemVer 0.x 记为 **MINOR**;不是 PATCH(无既有版本可修),未到 MAJOR(API 未冻结)。

## 四、里程碑与出口条件

| 编号 | 名称 | 内容 | 出口条件(全部满足) |
|---|---|---|---|
| **M0** | 骨架与结构验证 | 建 `moon.mod`、分包骨架、探针、`scripts/cross-riscv.sh`、CI 骨架;回答未知 A(`moon package --list` 是否含 `kernel.c`)与未知 B(子包 target 分派) | `moon build --target native` exit 0;`moon build --target wasm-gc` exit 0;两后端探针返回值不同(native=x+1,wasm-gc=x+2);`bash scripts/cross-riscv.sh` exit 0 且 qemu 输出 RV64 探针值;`moon package --list` 结论与结构选择写入计划 M0 结论 |
| **M1** | 标量实现与测试 | 5 个原语的纯 MoonBit 实现;`tests/` 黑盒用例覆盖空/单元素/全同/递增/极值/非 4 倍数 | `moon test --target wasm-gc` exit 0 且 passed ≥ 30;`moon test --target native` exit 0 且 passed ≥ 30;`moon fmt --check` exit 0 |
| **M2** | RVV 实现与交叉 | `kernel.c` 五函数双分支;`scripts/cross-riscv.sh` 生成 cc+ar wrapper与 sysroot 配方;`docs/NATIVE_ABI.md`、`docs/CROSS_COMPILE.md` 落地 | 三档(native C 标量 / RVV / wasm 标量)对 n=1,2,3,5,7,17,1024 逐元素结果相等;`readelf -h` 显示 RISC-V;qemu 运行 exit 0;两文档中的命令可从干净目录执行 |
| **M3** | 基准 | 5 原语 × 3 档 × 3 规模;主指标 spike 退休指令数;`docs/BENCHMARKS.md` | `bash scripts/bench.sh` exit 0;生成 `bench/results.md`,9 行均含 VLEN/编译器/N/REPS/checksum;三档 checksum 相同;产物不含 rdcycle 数字 |
| **M4** | 文档与发布门禁 | README/CONTRIBUTING/AGENTS/CHANGELOG/docs 定稿;发布检查 | `docs/RELEASE_CHECKLIST.md` 每条勾选并附命令输出;干净目录按 README 安装后 S1/S2 通过;`moon publish --dry-run` exit 0;实际发布等人类口令 |

> 判定点:每个里程碑做完,执行者停下报「待审核」;lead 独立复跑后才置 ✅。

### M0 细则(当前)

1. 建 `moon.mod`(`aurasuisui/rvv`,0.1.0,Apache-2.0)。
2. 按 3.3 建骨架;`lib.mbt` 先暴露 `pub fn rvv_probe_add`,标量与 native 返回**不同**占位值(M1 替换为 5 原语)。
3. `kernel.c` 放 `int32_t rvv_probe_add(int32_t)`;native 返回 x+1,wasm-gc 返回 x+2。
4. 未知 A:`moon package --list` 是否包含 `kernel.c`。
5. 未知 B:target 条件导入/文件级 `targets` 是否让两个后端选中不同实现。
6. 交叉:`scripts/cross-riscv.sh` 生成含 `cc` 与 `ar` 的目录,设置 `MOON_CC`;产物用 `qemu-riscv64 -L /usr/riscv64-linux-gnu` 运行。

## 五、端到端验收场景

| 编号 | 场景 | 期望 |
|---|---|---|
| S1 | wasm-gc 用户调 `sum` | 正确,走标量 |
| S2 | native x86 用户调 `sum` | 正确,走 C 标量 |
| S3 | RV64 交叉编译后调 `sum` | 正确,走 RVV |
| S4 | 5 原语 × 6 类边界 | 与标量一致;仅 `dot` 长度不等 panic |
| S5 | `prefix_sum` 原地语义 | 返回 Unit,数组就地改写 |
| S6 | `filter` | 保序,长度等于 `count_ge` |
| S7 | 发布包在干净目录 | `moon add` 后 S1/S2 通过 |
| S8 | 基准脚本 | 一条命令出 5×3 表 |

## 六、进度看板

| 里程碑 | 状态 | 证据 |
|---|---|---|
| **M0** | ✅ | f069586 合并前独立复跑:native=42、wasm-gc=43、`moon package --list` 含 `src/native/kernel.c`、cross-riscv 输出 42、`moon fmt --check`/`moon check` exit 0 |
| **M1** | ✅ | 5e2062f..8de3cbf;独立复跑:`moon test` wasm-gc/native 各 40/40、probe `15,3,35,325`、`moon fmt --check`/`moon check` exit 0;dot panic 回归用例已入库 |
| **M2** | ✅ | d620d50..b2921df;独立复跑:40/40×2、probe native `SELFTEST_PASS`+冒烟、cross-riscv exit 0(vsetvli=19、vle32=12、qemu 8.2 跑通)、`moon fmt --check`/`moon check` exit 0;host 测试产物有 6 处 `call rvv_*` |
| **M3** | ✅ | 6fb7eb1..93817be;独立复跑:`bash scripts/bench.sh` exit 0(45 行、两遍逐位相同、三档 checksum 全同)、`bench_control.sh` exit 0(控制表与 §4.4 一致)、cycle CSR 0 命中;`moon check`/`fmt`/40/40×2 未回归 |
| **M4** | 🚧 | T0–T3 独立复跑全绿(40/40×2、cross `SELFTEST_PASS`、bench `BENCH_OK`+45 行+对拍 `PARITY_OK`、control `CONTROL_OK`、package zip 干净目录 40/40);T4.1 `moon publish --dry-run` = 255(`Registry login is required`),T4.2–4.5 未执行,待人类登录/发布 |

## 七、缺陷/风险台账

| ID | 现象与位置 | 关闭条件(可验证) |
|---|---|---|
| **D1** | 发布包不含 `native-stub` 的 `kernel.c`,native 用户链接失败 | `moon package --list` 含 `kernel.c`;否则降级方案写进 README 且本地安装后 native 构建 exit 0 |
| **D2** | 子包 target 导入不可用或 selected 错文件 | M0 结论记录结构选择;`moon build --target wasm-gc` exit 0 且探针走标量值 |
| **D3** | `MOON_CC` 需同目录 `ar`,目标 ELF 需 sysroot;未写进文档 | `scripts/cross-riscv.sh` 在干净 WSL exit 0;缺依赖时报错含修复命令 |
| **D4** | `FixedArray[Int]` 与 C 的 `int32_t*` 布局/所有权不一致 | 跨 FFI 测试 n=1,2,3,5,7,17,1024 逐元素相等;`docs/NATIVE_ABI.md` 记录 |
| **D5** | RVV 尾部(非 VL 整数倍)处理错误 | n=1,2,3,5,7,17 的 5 原语测试通过 |
| **D6** | Windows/MSVC 对 `native-stub` 不可用 | M0 探针给出结论;不支持则 README 明写"Windows native 暂不支持" |
| **D7** | QEMU 的 rdcycle/rdinstret 被当周期用 | `grep -R "rdcycle" bench scripts` 0 命中;BENCHMARKS 写明口径 |
| **D8** | 基准只测 C 镜像,不测 MoonBit 产物 | `docs/BENCHMARKS.md` 有"限制"小节,结论措辞为"C 内核" |
| **D9** | 文档漂移/死文件 | 所有文档在 `docs/README.md` 登记;每次里程碑审核检查其 diff |

## 八、执行与审核规则

- 一次只派一个里程碑;执行者只报「待审核」,不自评通过。
- 四件必报:验证命令原样输出 / 测试计数 / commit 列表 / 做法与偏离。
- lead 必须独立复跑同一命令,并检查 `git diff --stat` 与禁止文件。
- 不可逆动作(发布、打 tag、合并主分支、删文件、强推)必须人类确认。
- 异常(失败、结果不符)立即停,不做补救式重试。

## 九、砍尾顺序

**不可砍**:5 原语在 wasm-gc 与 native 的正确性;RVV 分支与标量逐元素相等;spike 指令数口径;`docs/README.md` + `docs/SPEC.md` + `docs/CROSS_COMPILE.md`;Git 分支模型。

**可砍**(按序,砍了在 CHANGELOG 留痕):

1. 64K 规模基准 → 只保留 1K/8K。
2. 自动向量化档 → 只留标量与手写 RVV。
3. Windows/MSVC 支持声明。
4. GitHub Actions 的 RVV 作业(保留主机门禁)。
5. `moon publish --dry-run` 与干净目录安装(改用本地路径验证)。

## 十、文档落点

| 改动 | 唯一落点 | 联动 |
|---|---|---|
| API 语义/边界/panic/回绕 | `docs/SPEC.md` | README API 表、CHANGELOG |
| 安装/用法/配方入口 | `README.md` | docs/README 地图 |
| 交叉编译步骤/约束 | `docs/CROSS_COMPILE.md` | README、AGENTS 命令 |
| MoonBit↔C ABI | `docs/NATIVE_ABI.md` | SPEC 的 ABI 小节 |
| 性能数字/方法/限制 | `docs/BENCHMARKS.md` | README 只放链接与结论 |
| 分支/提交/测试/文档同步 | `CONTRIBUTING.md` | AGENTS 摘要 |
| 发布步骤与门禁 | `docs/RELEASE_CHECKLIST.md` | CHANGELOG |
| 文档增删 | `docs/README.md` 地图 | CONTRIBUTING 同步约定 |

## 十一、已决与已知债

**已决**:

- D1: `dot` 长度不等 panic,不截断。
- D2: `prefix_sum` 按 32 位回绕,不改 Int64。
- D3: v0.1.0 不含 `@v128` 与浮点。
- D4: 编译期分支,不做运行时 CPU 探测。
- D5: 性能只认 spike 指令数。
- D6: 仓库放 `Desktop\\moonbit-dev\\moonbit-rvv`。
- D7: 文档体系采用 bimap 式 SSOT + docs 枢纽。
- D8: `main` 只收里程碑合并,工作分支按里程碑开。

**已知债**:

- 基准测的是等价 C 内核,不是 MoonBit 生成产物(M3 记录)。
- 无 RISC-V 硬件;所有 RVV 结论来自 qemu/spike。
- CI 跑不了 RVV(ubuntu-22.04 的 qemu 6.2),RVV 走本地脚本。
- Windows/MSVC 的 native-stub 未验证(M0 给结论)。
- `pkg.generated.mbti` 接口快照未入库;若启用 `moon info` CI 门禁,在 M4 前决定并入。

## 十二、待决

| 项 | 选项 | 建议 |
|---|---|---|
| 是否公开 + 参赛 | 是/否 | 若参赛:公开仓库、连续提交、README 与测试齐备 |
| CI 范围 | 仅 wasm/native / 加 ubuntu-24.04 RVV | 先只跑前者 |
| v0.2.0 方向 | `@v128` / LMUL 调优 / 浮点 | 先 `@v128` |

## 附录 A:首轮基准(N=8192、REPS=4、VLEN=128、spike 退休指令数)

| 内核 | 标量 | 自动向量化 | 手写 intrinsics |
|---|---|---|---|
| scan | 163,881 | 163,875 | 237,622 |
| count | 147,648 | 28,752 | 81,972 |
| filter | 229,714 | 213,762 | 122,934 |

## 附录 B:常用命令

```bash
moon check
moon test --target wasm-gc
moon test --target native
moon fmt --check
moon package --list

# 交叉编译(WSL)
bash scripts/cross-riscv.sh
qemu-riscv64 -L /usr/riscv64-linux-gnu ./_build/.../main.exe

# 基准(spike)
~/spike/bin/spike --isa=rv64gcv_zicntr bench/bench.elf
```

## 附录 C:M0 结论(执行后追加)

**结论(2026-11-13,lead 独立复跑)**

- **未知 A(发布包是否含 C)**:含。`moon package --list` 第 18 行 = `src/native/kernel.c`;发布 zip `_build/publish/aurasuisui-rvv-0.1.0.zip` 同样包含该文件。D1 在本工具链的本地打包路径上未复现。
- **未知 B(target 分派)**:条件包导入不可用——`import { "…/native" } for "native"` 报 `Parsing error: unexpected token "native"`(带引号/不带引号/其他 target 同样失败;只有 `for "test"` 可用);`supported_targets = "-all+native"` 的子包在 wasm-gc 构建时报依赖图不兼容。已采用单包 + 文件级 `targets` 回退,并用两个后端的探针值(native=42、wasm-gc=43)证明分派正确。
- **交叉**:`scripts/cross-riscv.sh` exit 0;产物 `ELF64 … UCB RISC-V … double-float ABI`;`readelf -h` Machine=RISC-V;qemu-riscv64 输出 42。
- **基线修复**:`moon.mod` 的 `keywords` 由多行改为工具链要求的单行(纯排版),使 `moon fmt --check` exit 0。
- **未提交项**:`src/pkg.generated.mbti` 与 `src/probe/pkg.generated.mbti` 由构建生成;M0 不提交,M1 随真实 API 决定是否纳入快照并在 CI 加 `moon info` 门禁。
- **证据**:分支 `milestone/m0-skeleton`,commit `f069586`;lead 复跑命令见 `docs/plans/v0.1.0.md` 看板与本节。
