feat(all): 数据库模块化拆分与版本化迁移、任务引擎命名体系收敛、物理输出校验加固与用户配置接通
- server/db: 拆 4929 行 db.rs 单体为 db/ 目录,migrations.rs 引入 PRAGMA user_version
版本化迁移运行器(M1~M13)
- 任务引擎 Phase 6/7b/7c 改名收敛:EngineStageConfig→PhaseConfig、StagePolicy→ResumePolicy、
Converged→Completed、删除 task_type 列、success_method 拆 tlusty_/synspec_ 双列、
新增 tlusty_status/synspec_status 半失败阶段守卫
- 科学正确性加固:conv_check 任意行 NaN/Inf/溢出判无效(0 行容忍)、新增 spec_is_valid
校验 SYNSPEC 脏谱、itek_history 逐次迭代全量保真、fmt_abn powf 溢出饱和
- 用户配置真正接通:tlusty_chain/tlusty_input 由死字段经 调度器→TaskSpec→executor→runner
透传生效;config 加载期 validate + deny_unknown_fields + 解析失败记 warn
- 调度修复:H1 活锁(pending_strategies 跳过已失败策略)、种子查找错误不再静默降级冷启动
- dashboard: 阶段配置面板 tlusty_stage/synspec_stage、"已完成"标签、迭代诊断展示
- docs: 新增 database_refactor_design.md,同步 database/api/PIPELINE/workflow_detail
This commit is contained in:
@@ -84,8 +84,8 @@ struct CandidateResult {
|
||||
src_dir: PathBuf,
|
||||
/// 权威新名(来自 workflow 配置的小数精度命名)。
|
||||
canonical_name: String,
|
||||
/// 该点当初的收敛途径("cold_run" / "seed_step"),据 stages 是否含 seed_nc 判定,
|
||||
/// 透传给服务端写入 grid_points.success_method,让导入点融入冷启动/种子步进统计。
|
||||
/// 该点当初的大气收敛途径("cold_run" / "seed_step"),据 stages 是否含 seed_nc 判定,
|
||||
/// 透传给服务端写入 grid_points.tlusty_success_method,让导入点融入冷启动/种子步进统计。
|
||||
success_method: String,
|
||||
}
|
||||
|
||||
@@ -256,10 +256,10 @@ fn candidate_cno_sum(c: &CandidateResult) -> f64 {
|
||||
/// 从 workflow 配置派生收敛链最后阶段标签。
|
||||
///
|
||||
/// 旧版 run_one.py 每阶段覆盖同名 .5/.6/.err/nst,只留最后阶段的版本。迁移时需把这些
|
||||
/// 裸文件归到正确的阶段标签下。标签取自配置 chain 的末段;chain 为空则回退到默认收敛链
|
||||
/// 裸文件归到正确的阶段标签下。标签取自配置 tlusty_chain 的末段;为空则回退到默认收敛链
|
||||
/// 的末段(default_cold_chain 末段是 nl)。
|
||||
fn derive_last_stage_label(cfg: &GridConfig) -> String {
|
||||
if let Some(last) = cfg.chain.last() {
|
||||
if let Some(last) = cfg.tlusty_chain.last() {
|
||||
return last.label.clone();
|
||||
}
|
||||
// chain 为空(仅 grid,无 chain 配置):回退到默认收敛链末段。
|
||||
@@ -330,7 +330,21 @@ async fn scan_dir_for_results(
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if !(summary.converged && !summary.atmosphere_has_nan && !atmosphere_has_nan(&seed_file)) {
|
||||
if !summary.result_valid {
|
||||
info!("跳过 {}: conv.json 标记未收敛 (converged=false)", name);
|
||||
continue;
|
||||
}
|
||||
if summary.atmosphere_has_nan {
|
||||
info!("跳过 {}: conv.json 标记大气含 NaN/Inf", name);
|
||||
continue;
|
||||
}
|
||||
// 收紧阈值后(0 行容忍),对种子 .7 文件做二次校验。旧 run_grid 产物若含单行
|
||||
// NaN(此前 10% 阈值放过)会被这里拒绝——记日志便于排查"为何某历史种子被拒"。
|
||||
if atmosphere_has_nan(&seed_file) {
|
||||
info!(
|
||||
"跳过 {}: 种子 .7 文件含 NaN/Inf/溢出行(0 行容忍阈值)",
|
||||
name
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -361,7 +375,7 @@ async fn scan_dir_for_results(
|
||||
continue;
|
||||
};
|
||||
|
||||
// 判定该历史点的收敛途径(供服务端写入 success_method,让导入点融入冷启动/种子步进统计):
|
||||
// 判定该历史点的大气收敛途径(供服务端写入 tlusty_success_method,让导入点融入冷启动/种子步进统计):
|
||||
// 旧 run_grid.py 流程——冷启动失败才改用 seed_step 链重跑,种子链首段 label 为 "seed_nc"。
|
||||
// 故 stages 含 seed_nc → seed_step(种子步进救活);否则 → cold_run(冷启动一次收敛)。
|
||||
let has_seed_nc_stage = summary.stages.iter().any(|s| s.label == "seed_nc");
|
||||
@@ -680,11 +694,11 @@ async fn upload_results_to_server(
|
||||
.file_name(format!("{}.7", c.canonical_name))
|
||||
.mime_str("application/octet-stream")?,
|
||||
)
|
||||
// 收敛途径(cold_run/seed_step):服务端据此写 grid_points.success_method,
|
||||
// 大气收敛途径(cold_run/seed_step):服务端据此写 grid_points.tlusty_success_method,
|
||||
// 让导入点融入冷启动/种子步进统计而非独立 imported 分类。
|
||||
// Part::text 需 'static 生命周期,克隆一份脱离 candidates 借用。
|
||||
.part(
|
||||
"success_method",
|
||||
"tlusty_success_method",
|
||||
Part::text(c.success_method.clone()).mime_str("text/plain")?,
|
||||
);
|
||||
|
||||
@@ -961,7 +975,8 @@ mod tests {
|
||||
let v: serde_json::Value = serde_json::from_str(&rewritten).unwrap();
|
||||
assert_eq!(v["name"].as_str().unwrap(), "t20000_g5.0_he-2_c-4_n-4_o-4");
|
||||
assert_eq!(v["params"]["logg"].as_f64().unwrap(), 5.0);
|
||||
assert!(v["converged"].as_bool().unwrap());
|
||||
// 旧键 "converged" 经 alias 读入 result_valid,重写后按新键名写出。
|
||||
assert!(v["result_valid"].as_bool().unwrap());
|
||||
assert_eq!(v["final_max_relc"].as_f64().unwrap(), 0.001);
|
||||
// 格式对齐本项目计算生成的 conv.json(runner.rs:597 to_string_pretty(&ModelSummary)):
|
||||
// pretty 多行缩进 + 字段按 ModelSummary 声明顺序(name 为首字段,非字母序)。
|
||||
@@ -1016,8 +1031,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_derive_last_stage_label_from_chain() {
|
||||
// 配置显式指定 chain → 取末段标签
|
||||
let yaml = "grid:\n teff: [20000]\n logg: [5.0]\n loghe: [-2]\n logc: [-4]\n logn: [-4]\n logo: [-4]\nchain:\n - {label: lte, lte: T, ltgray: T, ilvlin: 0, require_converged: false, niter: 0}\n - {label: nc, lte: F, ltgray: F, ilvlin: 0, require_converged: false, niter: 10}\n - {label: nl_final, lte: F, ltgray: F, ilvlin: 100, require_converged: true, niter: 100}\n";
|
||||
// 配置显式指定 tlusty_chain → 取末段标签
|
||||
let yaml = "grid:\n teff: [20000]\n logg: [5.0]\n loghe: [-2]\n logc: [-4]\n logn: [-4]\n logo: [-4]\ntlusty_chain:\n - {label: lte, lte: T, ltgray: T, ilvlin: 0, require_converged: false, niter: 0}\n - {label: nc, lte: F, ltgray: F, ilvlin: 0, require_converged: false, niter: 10}\n - {label: nl_final, lte: F, ltgray: F, ilvlin: 100, require_converged: true, niter: 100}\n";
|
||||
let cfg = GridConfig::from_yaml_str(yaml).unwrap();
|
||||
assert_eq!(derive_last_stage_label(&cfg), "nl_final");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user