# LinAlg **Repository Path**: Lss__sjk/linalg ## Basic Information - **Project Name**: LinAlg - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-10 - **Last Updated**: 2026-01-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: 工作区 ## README # LinAlg-E 提交与评测说明(简要) 本仓库用于参赛“基于状态空间与矩阵运算的 EKF 设计”赛题。初赛要求:仅提交一个动态库和头文件(`contest.so` + `contest.h`),使用官方平台的 gcc 编译;矩阵一律按行优先写入一维数组;下标从 0 开始;所有函数返回值:`0` 成功,`1` 任何异常。 ## 目录结构 - `include/contest.h`、`src/contest.c`、`Makefile`:提交库的实现与构建脚本(已按《核心任务2和3的格式要求.pdf》对齐)。 - `contest.h`、`contest.so`:根目录放置的交付文件(本机 x86_64 验证用,正式需在官方平台重编)。 - `tests/test_main.c`:最小自测程序(非提交物)。 - `matrix_benchmark.c`、`matrix_benchmark`:单文件性能/正确性基准(float 实现,便于对比,不参与提交)。 - `variants/`:不同优化策略的实验代码(独立可编译的 benchmark 版本)。 - `比赛介绍/`:官方材料与《核心任务2和3的格式要求.pdf》。 - `优化文档.md`、`实验记录.md`:以往机器上的优化与实验记录(本机不同,结果会有差异)。 ## 快速开始(构建与自测) - 在当前机器(x86_64)快速构建并做最小验证: ```bash make # 生成 contest.so make test # 运行轻量自测(覆盖接口与基本正确性) ``` - 查看导出符号与架构: ```bash file contest.so nm -D contest.so | rg 'MQUERY|MFILL|MADD|MSUB|MDOTMUL|MDOTDIV|MMUL|MTRN|MINV|EKF_func' ``` ## 在官方评测机(aarch64)重编并打包 官方环境:Linux/aarch64、gcc、单核限制。到评测机上: ```bash make # 生成 aarch64 版本 contest.so cp include/contest.h ./contest.h # 提交 contest.h + contest.so 两个文件 ``` 可用 `file contest.so` 确认是 `ELF 64-bit LSB shared object, ARM aarch64`。 ## 接口摘要(详情见 `include/contest.h`) - Core-1(数据流输入,已并入提交库): - `STREAM_init/STREAM_reset/STREAM_feed/STREAM_has_frame/STREAM_get/STREAM_free` - 帧格式:魔数 `0x4d,0x54`('M','T')→ 8 字节头(`rows, cols, payload_bytes`,小端)→ 负载(row-major 的 `double` 数组)→ `CRC32`(4 字节)。 - 用途:在不修改评测 benchmark 的前提下,可作为通用矩阵输入接收器;不调用时对任务二/三零开销。 - Core-2:`MQUERY`、`MFILL`、`MADD`、`MSUB`、`MDOTMUL`、`MDOTDIV`、`MMUL`、`MTRN`、`MINV` - 行优先、0 基下标;异常(越界、维度不匹配、除数 0、不可逆等)返回 1,输出可不写。 - Core-3:`EKF_func(const EKF_INPUT*, EKF_OUTPUT*)` - `EKF_INPUT`: `k` 步长;`X/U/Z` 为 `k×25` 行优先。 - `EKF_OUTPUT`: `W/V/J_A/J_H` 为 `25×25`;`RES` 为 `k×25`。 - 当前实现提供“可运行基线”(打印 25 个状态/测量方程),便于先过接口;后续可替换为你们的真实建模与 EKF 实现,接口不变。 ### Core‑1 使用示例(可选,自测时用,不修改官方 benchmark) ```c #include "contest.h" // 构造一帧 3×3 的矩阵(行优先 double)并喂给接收器 static void demo_stream() { CSTREAM* rx = NULL; STREAM_init(64, 64, &rx); // 伪造一帧:MT + header + payload + crc32(此处略,详见 tests/ 或集成方) // STREAM_feed(rx, bytes, len) 可分多次调用 int has = 0; STREAM_has_frame(rx, &has); if (has) { double M[9]; int r,c; STREAM_get(rx, &r, &c, M); // 使用 M ... } STREAM_free(rx); } ``` ## 如何在你的工程中使用 `contest.so` - 头文件:包含 `contest.h` - 链接:在可执行程序编译时加 `-L<路径> -l:contest.so` 或直接与 `contest.so` 同目录运行。 - 运行时:如放到同目录,可通过 `-Wl,-rpath,.` 或设置 `LD_LIBRARY_PATH`。 示例(与 `tests/test_main.c` 类似): ```bash gcc -O2 -std=c11 -Iinclude -L. -Wl,-rpath,. app.c -o app -l:contest.so ``` ## benchmark 用法(不同机器性能会不同) 官方 benchmark 不改动。本仓库自带两个仅用于本机评估的程序(不参与提交): ```bash # 任务二微基准(MINV/MMUL/MTRN;以“最慢一次 max”为主口径) CONTEST_BENCH_ITERS=20000 taskset -c 0 ./tests/contest_bench # 任务三基准(EKF 端到端;同样以 max 为主口径) EKF_BENCH_K=200 EKF_BENCH_RUNS=200 taskset -c 0 ./tests/ekf_bench ``` 说明:`variants/` 目录内还有若干单文件变体基准,仅用于研究不同优化策略的“趋势”,不会影响/修改评测用的 benchmark。 ## 主办方 EKF case1/case2 自测(推荐) 承办方反馈“case1 正常、case2 异常”时,建议用仓库自带的 dlopen 检查器做**可复现**自测,并把输出与 dump 文件给承办方: ```bash make tests/ekf_submit_check ./tests/ekf_submit_check --so=./contest.so --case=EKF/case1 --dump=/tmp/ekf_dump_case1 ./tests/ekf_submit_check --so=./contest.so --case=EKF/case2 --dump=/tmp/ekf_dump_case2 ``` 输出解释: - `rc`:`EKF_func` 返回值(0 成功,1 异常)。 - `bad`:输出矩阵/结果中是否出现 NaN/Inf(应为 0)。 - `eq_ok`:控制台打印的 25+25 条方程是否能在容差内重建 `J_A/J_H`(用于排查“打印格式/系数错位”)。 注意: - `EKF_INPUT/EKF_OUTPUT` 的维度是 **25**(任务三状态向量长度为 25,见 PDF),与任务二的“支持 50×50 以内矩阵运算”是两件事。 - 要验证 aarch64 的提交产物,必须在 aarch64 机器上运行该检查器(x86_64 无法 dlopen aarch64 的 `.so`)。 ### 一键生成“可提交证据包”(含日志/输出/矩阵 dump) 如需交付“测试结果 + 录屏”给承办方,推荐用脚本生成一个目录证据包,然后把该目录打包/录屏展示: ```bash chmod +x tools/case2_selftest.sh ./tools/case2_selftest.sh --so=./contest.so # 或:从源码当场编译再测(建议在评测机/aarch64) ./tools/case2_selftest.sh --src=sjk/test8/src/contest.c --cc=gcc --cflags='-O3 -fPIC -std=c11 -Wall -Wextra -Wno-unused-parameter -mcpu=neoverse-n2 -ffp-contract=fast -fno-math-errno -fno-trapping-math' ``` 输出目录会在 `scan_results/selftest_case2_YYYY-mm-dd_HHMMSS/`,包含: - `SELFTEST_LOG.txt`:机器信息/编译信息/运行日志 - `case2_check.txt`:检查器输出(rc/bad/eq_ok 等) - `ekf_stdout_case2.txt`:EKF_func 打印的 25+25 条方程(用于核对格式/行列) - `dump_case2/`:`W/V/J_A/J_H/RES` 文本文件(用于和承办方对照) ### 切换 50×50 专用乘法(B4) - 默认关闭(使用通用轻展开 B3)。 - 开启方式:编译时加入 `-DMMUL_50_SPECIAL=1`,例如: ```bash make clean all CFLAGS+='-DMMUL_50_SPECIAL=1' CONTEST_BENCH_ITERS=20000 taskset -c 0 ./tests/contest_bench ``` 若“max”稳定优于默认再考虑开启为默认;不同机器可能结果不同,请以本机实测为准。 ### 调参:MINV 的 LU 面板尺寸(A3b) - 编译期宏:`LU_IS`(行块)、`LU_JS`(列块);默认 8 与 10。 - 用法示例:`make clean all CFLAGS='-DLU_IS=10 -DLU_JS=12'` - 建议:用 `CONTEST_BENCH_ITERS=20000 taskset -c 0 ./tests/contest_bench` 评估,以 `MINV 50×50 max` 为主要判据。 ## 测试方法(contest.so 专用) - 功能测试: - `make test` 运行 `tests/test_main.c`,覆盖 Core-2 算子与 EKF_func 的基本路径(异常返回策略:0 成功、1 异常)。 - 性能测试(基线与对比): - 运行微基准(建议优先用环境变量控制迭代次数): ```bash make bench # 默认 1000 次 CONTEST_BENCH_ITERS=20000 make bench # 提高迭代次数 CONTEST_BENCH_ITERS=20000 ./tests/contest_bench --spd # SPD 场景测试(M*M^T+λI) ``` - 单核固定运行(推荐在评测机): ```bash taskset -c 0 ./tests/contest_bench --iters=20000 ``` - 结果口径:以 `max` 作为与赛事口径对齐的主指标;`avg/min` 仅参考。 - 记录规范:将命令、编译参数、CPU/频率、iters 值与输出粘贴进《实验记录.md》,便于回溯。 - 评测机(aarch64)重编与测试: ```bash make CFLAGS='-O3 -fPIC -std=c11 -Wall -Wextra -Wno-unused-parameter -mcpu=neoverse-n2 -fno-math-errno -ffp-contract=fast -fno-trapping-math' cp include/contest.h ./contest.h taskset -c 0 CONTEST_BENCH_ITERS=20000 make bench # 提交时仅交 contest.h + contest.so ``` ## 优化路线与清单 - 详见根目录《OPTIMIZATION_PLAN.md》,包含:阶段目标、步骤勾选项、编译与运行规范、验收标准。 - 每次优化我都会: - 1)在 `snapshots/` 下生成一个以日期_代号命名的快照(至少包含 `src/contest.c`); - 2)用 `tests/contest_bench` 在单核、固定迭代下测出 max/avg/min; - 3)把“快照路径 + 测试口径 + 结果”追加到《OPTIMIZATION_PLAN.md·实验记录》; - 4)保留失败或退化版本的快照,标注“弃用”,便于回溯。 ## 常见注意事项 - 提交库请确保:单线程(不要链接 OpenMP/BLAS)、双精度 `double`、接口与返回值符合 PDF 约定。 - `MINV` 采用 LU 分解 + 列主元 + 前/回代;若主元绝对值 < `1e-12` 视为不可逆并返回 1。 - `MTRN` 支持就地转置(内部使用临时缓冲)。 - aarch64 下 `MMUL` 默认启用 NEON 双元素向量累加路径(无外部依赖);其它架构走纯 C 轻展开内核。 - 如需提升性能,可在不改变接口与数值稳定性的前提下进行:分块乘法、缓存友好访存、减少临时分配、合适的编译参数等。 ## 资料 - 比赛接口与环境:`比赛介绍/核心任务2和3的格式要求.pdf`、`比赛介绍/机器环境` - 历史记录:`优化文档.md`、`实验记录.md`(不同机器上数据会不同) --- 有任何格式或接口变更通知,请将其同步到 `include/contest.h` 并在评测机上重新 `make` 生成新的 `contest.so`。