batch指令说明
batch 是 pSolve 批处理解算的总控制器:它读取控制文件,组织单次实验数据(session)的处理,并根据解算类型调度法方程构建、局部参数消元、全局求解和回代等任务。理解它的重点,是这些任务按什么顺序执行,以及各个子程序如何交接数据和状态。
这里沿着 enter → batch 这条调用链,介绍 BATCH_MAIN 和 BATCH 的主要工作。CTRLS、PRCES 等中间子程序先说明其作用,内部过程留到后面再讨论。
1 batch 指令
batch 以 progs/solve/batch/batch_main.f 为程序入口,将 batch.f 和其他源文件编译得到的目标文件及依赖库链接起来产生。这里的路径相对于 pSolve 源码目录。
通过 psolve 启动批处理解算时,通常先进入 enter,再由它启动 batch。enter 先准备好包含控制文件名、处理进程编号等信息的运行字符串,然后执行:
CALL USE_BUFFER ( NEWBUF, INT2(64), 'OWC' )
CALL RUN_PROG ( 'BATCH', 'PASS', INT2(0) )
这两行代码分别完成数据发送和程序启动。USE_BUFFER 将 NEWBUF 中的 128 字节写入管道;RUN_PROG 随后启动 batch,并通过命令行参数传入运行状态和用户标识。'PASS' 表示把后续执行交出去,正常情况下不再返回 enter 中这个调用点。因此,batch 启动时要接收两部分信息:一部分是命令行中的启动状态,另一部分是管道中的运行字符串。运行字符串包含控制文件的路径,控制文件的具体内容在后面的处理过程中读取。batch 也支持直接接收控制文件等命令行参数,不过据我所知,这种方式几乎没人使用。两种启动方式由 BATCH_MAIN 判断,完成各自的准备后,都调用 BATCH()。这里主要关注由 enter 启动的情况。
batch 整个程序的运行可以分为四个层次:
| 层次 | 主要程序 | 职责 |
|---|---|---|
| 入口 | BATCH_MAIN |
准备运行环境,接收启动信息,调用总控制子程序,并在正常返回后退出 |
| 总控制 | BATCH |
组织解算准备,调用处理程序,完成解算后的清理 |
| 解算准备 | CTRLS → CTRLFL |
展开、读取控制文件,检查数据,准备新的解算或恢复中断的任务 |
| 解算调度 | PRCES → ARCSET,以及各解算程序 |
按处理阶段逐一准备单次实验数据,调用计算程序并保存进度 |
实际承担法方程构建、求解和回代等计算工作的程序,还包括其他目录中的 PROC_DO、NORML_MAIN、BACK_DO 等。progs/solve/batch/ 目录主要负责围绕这些计算程序组织批处理流程。BATCH_MAIN 和 BATCH 分别定义在 batch_main.f 和 batch.f 中:前者管理程序入口和退出,后者组织批处理任务。
2 BATCH_MAIN
BATCH_MAIN 是 batch 的主程序。它先准备运行环境和启动信息,再调用 BATCH;BATCH 正常返回后,主程序记录完成信息、移除运行占用标记文件并退出。

BATCH_MAIN 的主要操作是:
- 准备运行环境。 设置进程栈大小和
GOMP_STACKSIZE,再调用PRE_PROG(),读取启动参数,准备 pSolve 运行所需的公共变量。 - 处理直接启动的情况。 如果命令行参数数目大于或等于 6,就读取控制文件名等信息,设置是否尝试恢复中断任务、恢复前是否询问,再构造运行字符串,并调用
MAKE_PIPES建立管道。 - 处理由
enter启动的情况。 通过USE_BUFFER接收上游传来的运行字符串。是否恢复中断任务等标志也由上游传入,在这个分支中不再重新设置。 - 执行批处理任务。 两种启动方式完成各自的准备后,都调用
BATCH(),进入批处理的主体部分。 - 记录完成信息并退出。
BATCH正常返回后,调用DBG_END()记录完成信息,通过REMOVE_SOLVE_LOCK()删除运行占用标记文件,最后由END_PROG()写入结束记录并退出。这里的运行占用标记文件名为LOCKxx,其中xx是 pSolve 的两字符用户标识。文件中记录程序名、用户、进程号和时间等信息,供程序判断这个用户标识是否正在被使用。REMOVE_SOLVE_LOCK做的就是删除这份标记文件。
3 BATCH
BATCH 是定义在 batch.f 中的子程序,由 BATCH_MAIN 调用。它按照已经收到的运行信息,读取控制文件、准备工作文件和辅助数据,再调用后续程序执行解算,最后完成清理。

BATCH 的主要操作是:
- 做好运行前的设置。 初始化警告信息、待合并矩阵列表和实验数等变量,调用
ERR_MODE设置出错时的处理方式,再通过GETENVAR和DEBUG_MEM,根据MEMORY_DEBUG的设置决定是否启用内存调试。 - 记录开始信息并计时。
STATUS_SET记录批处理已经开始,SET_SIGNAL_CTRLC设置按下 Ctrl+C 等情况下的处理方式,TIM_INIT开始计时。此外,程序通过CLRCH、GET_VERSION和KBIT准备并输出版本及恢复模式信息。 - 读取控制文件,准备解算。 调用
CTRLS,读取运行字符串和控制文件,为解算做好准备。如果本次需要恢复中断的任务,也在这一阶段处理。CTRLS返回后,BATCH保存待处理实验数、待合并的 CGM 和输出 CGM 名称等信息,再通过USE_GLBFIL('OW')和USE_GLBFIL_4('WC')写入GLBFxx工作文件,供后面的程序使用。 - 准备工作文件。 用
INQUIRE检查旧的约束文件,并调用UNLINK删除。用户偏导相关文件(USER_PARTIAL)则通过BIN_EXIST检查,根据解算类型和是否恢复任务,决定保留还是重建;相关操作涉及BIN_UNLINK以及OPEN、WRITE、CLOSE,相应分支中的错误由FERR处理。 - 准备 EOP 改正并合并 CGM。
SHFEOP()准备高频地球定向参数改正,并按配置读取改正文件。如果指定了需要合并的 CGM,就依次调用ADD_CGM处理;没有指定时,直接进入下一步。到这里,解算前的准备已经完成。 - 执行批处理解算。 调用
PRCES,由它按处理阶段逐一处理各次实验数据,并根据解算类型调用相应的计算程序。 - 完成清理并返回。
PRCES正常返回后,程序输出此前暂未打印的警告,通过FC_UNLINK删除展开后的.XPND控制文件,再由BATCH_CLEANUP()清理与中断恢复有关的记录。最后,STATUS_SET标记批处理结束,BATCH返回BATCH_MAIN。
解算过程中生成的文本报告称为 spool file,这里称为“解算输出报告”,一般位于 /scr/psolve/spool/SPLFxx,其中 xx 是 pSolve 的用户标识。报告中记录了参数估计结果、各次实验数据的统计信息和部分处理信息,具体内容由输出设置决定。文件大小随实验数量和输出内容而变化,大型解算的报告可能达到数百 MB。可以通过 getpar 从这份报告中提取我们感兴趣的结果,例如射电源位置、测站坐标和地球定向参数等,并分别保存为便于后续分析的文件。