9.3 KiB
9.3 KiB
TLUSTY Rust 重构规范
1. 选定下一个重构目标
优先处理依赖少无io的函数
注意:DATA 语句(硬编码的数据表)已经由scripts/extract_fortran_data.py生成到src/data.rs中
不要管复杂不复杂和有无common依赖, 按python3 scripts/analyze_fortran.py --priority | head -10 的顺序来
分离出来的原始fortran函数在/home/fmq/program/tlusty/tl208-s54/rust/tlusty/extracted文件夹下
优先级排序
核心原则: 优先处理"传递未实现依赖=0"的函数,它们不依赖其他未完成的函数。
按以下顺序选择待重构函数:
-
无未实现依赖 (传递未实现=0)
- 可立即开始,无需等待其他函数
- 包括纯函数和只有 COMMON 依赖的函数
-
少量未实现依赖 (传递未实现=1~3)
- 需要先完成少数依赖函数
- 用
--tree查看具体依赖链
-
多未实现依赖 (传递未实现>3)
- 依赖链较长,最后处理
- 或考虑整体重构策略
-
有 I/O 依赖的函数
- 最后处理,可能需要设计新的 I/O 抽象层
查询命令
CSV 列结构: fortran_file,unit_name,unit_type,is_pure,common_deps,call_deps,has_io,rust_module,status
依赖树分析
# 输出重构优先级列表(按未实现依赖排序,推荐!)
python3 scripts/analyze_fortran.py --priority
# 输出指定单元的依赖树
python3 scripts/analyze_fortran.py --tree UNIT_NAME
# 输出完整传递依赖的 CSV
python3 scripts/analyze_fortran.py --full > fortran_analysis_full.csv
优先级列表说明:
重构优先级列表 (按未实现依赖排序)
====================================================================================================
单元名 未实现 传递未实现 深度 直接调用 传递调用 IO
----------------------------------------------------------------------------------------------------
C 0 0 0 0 0 ○
ALIFR3 0 0 0 0 0 ○
- 未实现: 直接依赖中未完成的函数数
- 传递未实现: 所有递归依赖中未完成的函数数(关键指标!)
- 排序: 传递未实现少 → 深度低 → 依赖少
- 只显示未完成(pending)的函数
- IO 列: ○ = 无IO, ✓ = 有IO
依赖树输出示例:
依赖树: ALISK1 ○
============================================================
直接依赖: 4, 传递依赖: 27, 未实现: 20
未实现依赖: ALIFRK, OPACF1, OPADD, ROSSTD, ...
------------------------------------------------------------
○ ALISK1 (4未实现)
├── ○ OPACF1 (6未实现)
│ ├── ○ OPADD (5未实现)
│ │ ├── ○ cia_h2h2 (1未实现)
│ │ │ └── if [未找到/未实现]
│ │ └── ✓ locate
│ └── ...
└── ○ ALIFRK
- ✓ = 已完成, ○ = 待处理
(N未实现)= 该节点有 N 个直接依赖未完成- 顶部汇总:传递未实现依赖数及列表
- 子节点按未实现依赖数排序(多的在前)
按纯度筛选
无io的纯函数已经全部实现重构
按 I/O 筛选
# 有 I/O 的未完成函数 (最后处理)
awk -F, '$7=="True" && $9=="pending"' fortran_analysis.csv
# 无 I/O 的未完成函数 (优先处理)
awk -F, '$7=="False" && $9=="pending"' fortran_analysis.csv
# 无 I/O 且无调用依赖的未完成函数
awk -F, '$6=="" && $7=="False" && $9=="pending"' fortran_analysis.csv
按 COMMON 依赖筛选
# 只依赖 BASICS 的未完成函数
awk -F, '$5=="BASICS" && $9=="pending"' fortran_analysis.csv
# 依赖 BASICS 和 ATOMIC,但无其他依赖
awk -F, '$5 ~ /^BASICS\|ATOMIC$/ && $9=="pending"' fortran_analysis.csv
# 不依赖 MODELQ 的未完成函数 (MODELQ 最复杂)
awk -F, '$5 !~ /MODELQ/ && $9=="pending"' fortran_analysis.csv
# 列出所有不同的 COMMON 依赖组合
awk -F, '{print $5}' fortran_analysis.csv | sort | uniq -c | sort -rn
按状态筛选
# 所有已完成函数
awk -F, '$9=="done"' fortran_analysis.csv
# 所有进行中函数
awk -F, '$9=="in_progress"' fortran_analysis.csv
# 统计各状态数量
awk -F, '{print $9}' fortran_analysis.csv | sort | uniq -c
组合筛选
# 最佳候选:无 I/O + 无调用依赖 + 纯函数或简单 COMMON
awk -F, '$6=="" && $7=="False" && $9=="pending"' fortran_analysis.csv
# 次优候选:无 I/O + 有调用依赖但依赖已完成
awk -F, '$6!="" && $7=="False" && $9=="pending"' fortran_analysis.csv
# 查看特定函数的依赖信息
awk -F, '$2=="TARGET"' fortran_analysis.csv
按代码大小排序
# 按行数排序(选小的先做)
cd tlusty/extracted
wc -l *.f | sort -n | head -30
# 查看小文件 + 纯函数
for f in $(ls *.f); do
lines=$(wc -l < "$f")
name=$(basename "$f" .f)
if grep -q "True.*pending" ../../fortran_analysis.csv && [ $lines -lt 100 ]; then
echo "$lines $name"
fi
done | sort -n
快速查看
# 查看重构进度摘要
echo "已完成: $(awk -F, '$9=="done"' fortran_analysis.csv | wc -l)"
echo "待处理: $(awk -F, '$9=="pending"' fortran_analysis.csv | wc -l)"
echo "纯函数待处理: $(awk -F, '$4=="True" && $9=="pending"' fortran_analysis.csv | wc -l)"
echo "无IO待处理: $(awk -F, '$7=="False" && $9=="pending"' fortran_analysis.csv | wc -l)"
2. 重构流程
Step 1: 分析 Fortran 源码
# 查看源码
cat tlusty/extracted/TARGET.f
检查:
- INCLUDE 文件列表
- COMMON 块
- 调用的其他函数
- 是否有 I/O
Step 2: 创建 Rust 模块
# 创建文件
touch src/math/TARGET.rs
Step 3: 实现函数
遵循命名规范:
- Fortran
FUNCTION→ Rustpub fn - Fortran
SUBROUTINE→ Rustpub fn(返回值用参数或元组) - COMMON 块 → 结构体参数
Step 4: 添加到 mod.rs
// src/math/mod.rs
mod target;
pub use target::target;
Step 5: 编写测试
#[cfg(test)]
mod tests {
use super::*;
use approx::assert_relative_eq;
#[test]
fn test_target_basic() {
// 基本测试
}
}
Step 6: 运行测试
# 单个模块测试 (不要 cargo test 全量!)
cargo test target
Step 7: 更新追踪表
# 如果是一对一映射,脚本自动识别
python3 scripts/analyze_fortran.py > fortran_analysis.csv
python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md
# 如果是一对多映射,先更新 SPECIAL_MAPPINGS
3. SPECIAL_MAPPINGS 维护
何时需要更新
当一个 Rust 文件实现多个 Fortran 函数时,需要添加映射。
位置
scripts/analyze_fortran.py 第 72 行
格式
SPECIAL_MAPPINGS = {
# Rust 文件名 -> [Fortran 函数名列表]
'gfree': ['gfree0', 'gfreed', 'gfree1'],
'interpolate': ['yint', 'lagran'],
'sgmer': ['sgmer0', 'sgmer1', 'sgmerd'],
'ctdata': ['hction', 'hctrecom'],
'cross': ['cross', 'crossd'],
'expint': ['eint', 'expinx'],
'erfcx': ['erfcx', 'erfcin'],
# 新增映射...
}
添加新映射后执行
python3 scripts/analyze_fortran.py > fortran_analysis.csv
python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md
4. 状态更新流程
手动更新状态
如需手动标记状态,编辑 fortran_analysis.csv:
# status 列: done, pending, in_progress, skip
filename.f,UNIT,SUBROUTINE,False,"...",...,False,src/math/xxx.rs,done
然后重新生成 Markdown:
python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md
5. 代码规范
文件头注释
//! 模块简要说明。
//!
//! 重构自 TLUSTY `filename.f`
函数注释
/// 函数功能说明。
///
/// # 参数
///
/// * `x` - 参数说明
///
/// # 返回值
///
/// 返回值说明
///
/// # 示例
///
/// ```
/// use tlusty_rust::math::func;
/// assert!((func(1.0) - 2.0).abs() < 1e-10);
/// ```
pub fn func(x: f64) -> f64 { ... }
精度要求
| 函数类型 | 容差 |
|---|---|
| 简单数学运算 | 1e-10 |
| 多项式近似 | 1e-7 |
| f32 数组 | 1e-24 |
常见陷阱
| 问题 | 解决方案 |
|---|---|
| Fortran 1-indexed | arr(i) → arr[i-1] |
-LOG(X) |
是 -ln(X) 不是 ln(-X) |
| powi 类型歧义 | 用显式乘法 (a)*(a) |
| 矩阵列优先 | A(j,i) → a[(i-1)*N + (j-1)] |
6. 快速命令参考
# 查看重构进度
cat FORTRAN_TRACKING.md | head -20
# 进度统计
echo "已完成: $(awk -F, '$9=="done"' fortran_analysis.csv | wc -l)"
echo "待处理: $(awk -F, '$9=="pending"' fortran_analysis.csv | wc -l)"
# 推荐方式:查看优先级列表(按未实现依赖排序)
python3 scripts/analyze_fortran.py --priority | head -30
# 查看函数依赖树(含未实现依赖数)
python3 scripts/analyze_fortran.py --tree FUNCTION_NAME
# 找最佳候选:无IO + 无调用依赖
awk -F, '$6=="" && $7=="False" && $9=="pending"' fortran_analysis.csv | head -5
# 找纯函数
grep "True.*pending" fortran_analysis.csv | head -5
# 找无IO的函数
awk -F, '$7=="False" && $9=="pending"' fortran_analysis.csv | head -5
# 测试单个模块
cargo test module_name
# 更新追踪表
python3 scripts/analyze_fortran.py > fortran_analysis.csv && \
python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md
# 编译检查
cargo build 2>&1 | grep error