375 lines
9.3 KiB
Markdown
375 lines
9.3 KiB
Markdown
# 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"的函数,它们不依赖其他未完成的函数。
|
||
|
||
按以下顺序选择待重构函数:
|
||
|
||
1. **无未实现依赖** (传递未实现=0)
|
||
- 可立即开始,无需等待其他函数
|
||
- 包括纯函数和只有 COMMON 依赖的函数
|
||
|
||
2. **少量未实现依赖** (传递未实现=1~3)
|
||
- 需要先完成少数依赖函数
|
||
- 用 `--tree` 查看具体依赖链
|
||
|
||
3. **多未实现依赖** (传递未实现>3)
|
||
- 依赖链较长,最后处理
|
||
- 或考虑整体重构策略
|
||
|
||
4. **有 I/O 依赖的函数**
|
||
- 最后处理,可能需要设计新的 I/O 抽象层
|
||
|
||
### 查询命令
|
||
|
||
CSV 列结构: `fortran_file,unit_name,unit_type,is_pure,common_deps,call_deps,has_io,rust_module,status`
|
||
|
||
#### 依赖树分析
|
||
|
||
```bash
|
||
# 输出重构优先级列表(按未实现依赖排序,推荐!)
|
||
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 筛选
|
||
|
||
```bash
|
||
# 有 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 依赖筛选
|
||
|
||
```bash
|
||
# 只依赖 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
|
||
```
|
||
|
||
#### 按状态筛选
|
||
|
||
```bash
|
||
# 所有已完成函数
|
||
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
|
||
```
|
||
|
||
#### 组合筛选
|
||
|
||
```bash
|
||
# 最佳候选:无 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
|
||
```
|
||
|
||
#### 按代码大小排序
|
||
|
||
```bash
|
||
# 按行数排序(选小的先做)
|
||
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
|
||
```
|
||
|
||
#### 快速查看
|
||
|
||
```bash
|
||
# 查看重构进度摘要
|
||
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 源码
|
||
|
||
```bash
|
||
# 查看源码
|
||
cat tlusty/extracted/TARGET.f
|
||
```
|
||
|
||
检查:
|
||
- [ ] INCLUDE 文件列表
|
||
- [ ] COMMON 块
|
||
- [ ] 调用的其他函数
|
||
- [ ] 是否有 I/O
|
||
|
||
### Step 2: 创建 Rust 模块
|
||
|
||
```bash
|
||
# 创建文件
|
||
touch src/math/TARGET.rs
|
||
```
|
||
|
||
### Step 3: 实现函数
|
||
|
||
遵循命名规范:
|
||
- Fortran `FUNCTION` → Rust `pub fn`
|
||
- Fortran `SUBROUTINE` → Rust `pub fn` (返回值用参数或元组)
|
||
- COMMON 块 → 结构体参数
|
||
|
||
### Step 4: 添加到 mod.rs
|
||
|
||
```rust
|
||
// src/math/mod.rs
|
||
mod target;
|
||
pub use target::target;
|
||
```
|
||
|
||
### Step 5: 编写测试
|
||
|
||
```rust
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
use approx::assert_relative_eq;
|
||
|
||
#[test]
|
||
fn test_target_basic() {
|
||
// 基本测试
|
||
}
|
||
}
|
||
```
|
||
|
||
### Step 6: 运行测试
|
||
|
||
```bash
|
||
# 单个模块测试 (不要 cargo test 全量!)
|
||
cargo test target
|
||
```
|
||
|
||
### Step 7: 更新追踪表
|
||
|
||
```bash
|
||
# 如果是一对一映射,脚本自动识别
|
||
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 行
|
||
|
||
### 格式
|
||
|
||
```python
|
||
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'],
|
||
# 新增映射...
|
||
}
|
||
```
|
||
|
||
### 添加新映射后执行
|
||
|
||
```bash
|
||
python3 scripts/analyze_fortran.py > fortran_analysis.csv
|
||
python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md
|
||
```
|
||
|
||
## 4. 状态更新流程
|
||
|
||
### 手动更新状态
|
||
|
||
如需手动标记状态,编辑 `fortran_analysis.csv`:
|
||
|
||
```csv
|
||
# status 列: done, pending, in_progress, skip
|
||
filename.f,UNIT,SUBROUTINE,False,"...",...,False,src/math/xxx.rs,done
|
||
```
|
||
|
||
然后重新生成 Markdown:
|
||
|
||
```bash
|
||
python3 scripts/generate_tracking.py > FORTRAN_TRACKING.md
|
||
```
|
||
|
||
## 5. 代码规范
|
||
|
||
### 文件头注释
|
||
|
||
```rust
|
||
//! 模块简要说明。
|
||
//!
|
||
//! 重构自 TLUSTY `filename.f`
|
||
```
|
||
|
||
### 函数注释
|
||
|
||
```rust
|
||
/// 函数功能说明。
|
||
///
|
||
/// # 参数
|
||
///
|
||
/// * `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. 快速命令参考
|
||
|
||
```bash
|
||
# 查看重构进度
|
||
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
|
||
```
|