AGRI-JAX · 田块尺度作物–土壤模型

十万个生长季,同一天,一起算; 对照 DSSAT-CSM 逐日验证,并且可微。

Fig. 0

田块尺度的作物–土壤模型,写成纯 JAX 函数:依据已发表的方程独立实现,并对照 DSSAT-CSM(BSD-3 协议)与 RZWQM2 的输出进行验证。右侧的图随阅读变化:先是一个矩阵,行为生长季,列为天;随后是实测结果。

籽粒产量对 DSSAT-CSM 的偏差,59 个有籽粒生长季中的最大值65 个整季自由运行;出苗、吐丝、成熟日期 65 个全部一致
1.5 %
实测
单个 CPU 核上 10⁵ 个生长季,DSSAT-CSM ÷ Agri-JAX首次运行 · 热启动 · 重复调用
14× · 25× · 29×
实测
标定得到的品种系数写入 DSSAT 文件后,在 DSSAT-CSM 中重新运行日期一致,产量偏差在 0.1 % 以内
22 / 22
实测

上述倍率比较的是两个工作量不同的程序:DSSAT-CSM 写出完整的逐日文件并运行整个作物–土壤模型,Agri-JAX 只运行已验证的逐日模型并返回十条逐日序列。在 192 核整节点上,首次运行比 DSSAT-CSM 慢(0.85×);各行结果见第三幕。

向下滚动,图随阅读变化;也可以用图下方的按钮逐帧播放。悬停、聚焦或点击带下划线的数字,可查看其条件。

01一起算6 帧

十万个生长季:DSSAT-CSM 一个接一个地跑,Agri-JAX 一天一天地一起走

  1. 1.1DSSAT-CSM 在一个核上把 10⁵ 个生长季一个接一个地跑完:实测 1426 s,写出 30.3 GB 的逐日文本。屏幕上为加速播放。
  2. 1.2在同一个核上,Agri-JAX 每一步让所有生长季前进一天。首次运行(含编译)用时 99.1 s,热启动 56.0 s,重复调用 48.9 s;十条逐日序列留在内存中(1.5 GB),不写任何文件。相对 DSSAT-CSM,这里分别快 14× · 25× · 29×(首次运行 · 热启动 · 重复调用)。
  3. 1.3为什么可以换走法:每个格子只依赖同一行中它左边的格子,即一个生长季的今天只依赖它自己的昨天。
  4. 1.4行与行之间没有箭头:一个生长季的水分从不进入另一个生长季的方程。
  5. 1.5于是两层循环可以对调:外层循环遍历天,内层对每一行施加同一个操作。一列就是对十万个数的一条指令,这正是向量单元与 GPU 所擅长的形状。
  6. 1.6一列就是 DSSAT 的一天:土壤反照率与水桶模型的水量速率、潜在蒸散发、土面蒸发与蒸腾、根系吸水、水桶模型的状态更新、CERES-Maize 的生长,以及水量账。这一天的各个模块均由模型自行模拟;只有尚未移植的模块所产生的内容(残留物记录、逐日土壤性质变化)取自 DSSAT 回放。

同一个矩阵、同一比例尺,只是遍历顺序不同。两边所做的工作并不相同:DSSAT-CSM 运行整个作物–土壤模型,每个生长季写出 303 kB 的逐日文本;Agri-JAX 只运行已验证的逐日模型所含的模块,并返回十条逐日序列。因此这些倍率并非某一个数值内核的加速比。测于 AMD EPYC 9654 的一个绑定核(rorqual,2026年9月28日),每行仅测一次。格子颜色为示意。

现有的 Fortran 实现并不原生支持数组式的批量执行:全局状态与每次运行的文件读写把每个模拟绑定在单个进程上。这是实现方式的属性,而非语言本身的属性。

02对照 DSSAT-CSM 验证2 帧

65 个整季自由运行与 dscsm048 一致:产量、日期、逐日曲线与水量账

  1. 2.165 个生长季(DSSAT 玉米样例的 58 个处理,以及 AmeriFlux 玉米站点 CA-TPA 的 7 个生长季,共 11 138 天)均为自由运行:土壤水分、蒸发与根系吸水由 Agri-JAX 自行计算,而非读取自 DSSAT。在 59 个有籽粒的生长季中,产量最大偏差为 1.5 %,中位数为 4.0e-5;验收上限为 2 %。出苗、吐丝与成熟日期在 65 个运行中全部一致。逐日 LAI 的 RMSE 最大为 0.0061,剖面土壤水分最大为 0.33 mm,每日水量账闭合到 6.6e-14 mm。
  2. 2.2一个生长季的逐日对照,UFGA8201 处理 4(灌溉、高氮,即第四幕中标定的处理):LAI、生物量、籽粒质量与剖面土壤水分均与 DSSAT 的曲线重合。最大差异为 LAI 0.0048、生物量 0.54 kg/ha、土壤水分 0.5 mm,均在 DSSAT 自身输出文件的打印取整范围之内。

氮素关闭,CPU 上 float64,参考为 dscsm048 build 486(DSSAT-CSM 4.8.6.0)。只有这一天的各个模块都不产生的内容才取自 DSSAT 回放:有机质模块的残留物记录与逐日土壤性质变化。样例处理与 DSSAT 在其打印分辨率的水平上一致;CA-TPA 生长季在逐日蒸散发与土壤水分上比打印分辨率高 5 至 18 倍。

各模块也分别单独检验过。在 DSSAT 自身的输入上逐日检验,XTRACT 根系吸水在 1.03 个、潜在蒸散发在 4.7 个、土壤反照率在 4.5 个 REAL*4 舍入单位以内。仅运行 CERES-Maize,由 DSSAT 的土壤水分与蒸腾驱动:逐日 LAI 偏差在 0.50 % 以内,生物量 0.63 %,产量 0.030 %,生育阶段逐日一致。

03速度3 帧

同一任务、同一计时边界:重复调用优势明显,一次性运行则各有胜负

  1. 3.1在同一计时边界下模拟 10⁴ 与 10⁵ 个生长季。在单个核上模拟 10⁵ 个生长季,DSSAT-CSM 用时 1426 s;Agri-JAX 首次运行 99.1 s,热启动 56.0 s,重复调用 48.9 s。32 核上的倍率为 2.3×、4.1×、22×。在 192 核整节点上,DSSAT-CSM 用时 17.4 s:Agri-JAX 的首次运行较慢(0.85×),热启动快 1.6 倍,重复调用快 25 倍。
  2. 3.2GPU:定位瓶颈、调整程序布局、核对模型不变。对一块 H100 的剖析显示,每个模拟日约有 490 个短内核,设备空闲 34–45 %。展开层循环(一项按后端选择的执行设置,过程代码不变)后,只剩 60–63 个内核、空闲 2–3 %,重复调用快 3.1 倍(10⁵ 个生长季时由 1.31 s 降至 0.42 s)。代价是编译变长(19 → 67 s)。核对:GPU 与 CPU 相比,65 个运行的阶段日期全部一致,产量相差不超过 1.4e-15;GPU 上展开与循环相比,产量、土壤水分、径流与排水逐位一致。
  3. 3.3Agri-JAX 在生长季多、核数少时更划算,在同一数组形状下反复调用(标定、敏感性分析、集合模拟)时优势最大:重复调用在所测的每种 CPU 设置上都比 DSSAT-CSM 快 22–29 倍。只跑一次、至多 10³ 个生长季,用 DSSAT-CSM 就够了。表里按任务列出用什么工具、怎么设置。

任务:将 65 个验证生长季复制到 B 个生长季(平均每季 171 天),float64,向主机返回十条逐日序列。Agri-JAX 对每个样本的 7 个参数施加 U(0.9, 1.1) 的扰动;DSSAT 的各个副本不加扰动。硬件:rorqual(Calcul Québec),2 × AMD EPYC 9654(192 核),一整块 NVIDIA H100(主机为 Xeon Gold 6448Y),JAX 0.10.2。“单核”指一个绑定核,“32 核”指在此类节点上申请的 32 核分配,而非 32 核工作站。每个单元格仅测量一次;同一节点上不同进程间,重复调用时间的差异最大可达 20 %。CPU 各行测于 2026年9月28日,H100 各行测于 2026年9月29日。

两边的工作量不同:DSSAT-CSM 在 10⁵ 个生长季时写出 30.3 GB 的逐日文本并运行整个作物–土壤模型,Agri-JAX 返回 1.5 GB 的十条序列。与仅输出汇总的 DSSAT-CSM 相比,单核倍率约减半(重复调用为 15 倍而非 29 倍),整节点倍率不变。H100 所在主机上未运行 DSSAT-CSM,因此 GPU 不给出倍率。未测量,故不给出倍率的情形:10⁶ 个及以上生长季、T4 或 Colab GPU、笔记本电脑。

04标定4 帧

一次调用即可将品种系数拟合到观测上,并写出 DSSAT 能读回的一行

  1. 4.1calibrate(...) 读取 DSSAT 玉米试验的处理与观测,以批量联合 CMA-ES 拟合六个品种系数,按候选值写入 .CUL 行之后的取值挑选最优候选(每个数字 5 个字符,舍入可使日期相差一天),写出该行并用它运行 dscsm048。以 UFGA8201 为例:目标函数由 1.015 降至 0.0100,留出处理由 1.046 降至 0.0239,以写出的行运行 DSSAT,产量与 Agri-JAX 相差不超过 2.9e-4。22 个往返检验运行中,全部 22 个日期一致,产量偏差在 0.1 % 以内。
  2. 4.2可辨识性。仅凭日期、产量、生物量与 LAI,G2 与 G3 沿损失函数的一条弯曲谷地分布:24 次重新标定散布在 G2 355–982、G3 7.6–16.4 之间。加入粒数后,谷地收拢到已发布值附近(G2 831–984,G3 7.5–9.4),留出处理的粒数误差(各种子的最优拟合):−51…−49 % → −7…−6 %。代价是雨养处理 2:其产量误差由 −5 % 增大到 −41 %,原因是模型在水分胁迫下低估了粒数。
  3. 4.3为什么默认采用联合 CMA-ES。从无噪声的合成观测中恢复已知品种(264 次拟合),225 次拟合达到目标,分阶段方案为 212 次(该方案使用梯度),耗时 135 s 对 210 s。分阶段方案每次拟合所需的模型调用较少(443 次前向与 51 次梯度调用,联合方案为 1008 次前向调用)。
  4. 4.4梯度按适用范围分级:前向模型已通过验证;部分系数的梯度可用;穿过物候事件的梯度属于实验性质。在一块 H100 上,对 10⁴ 个生长季求籽粒总质量关于五个系数的一次梯度:层循环展开时用时 1.81 s(循环时为 5.02 s),代价是编译 316 s,而循环时为 64 s。

我们不声称标定比 DSSAT-CSM 更快。对上述合成任务,联合 CMA-ES 在 192 核节点上的实测耗时,介于同一节点上理想并行的 DSSAT-CSM 估计值的 1.6 倍慢与 1.2 倍快之间;该估计由实测的每季耗时推算,并非在 DSSAT-CSM 中实际运行标定。损失函数等高线是条件切片(其余系数固定在对实测观测拟合得到的最优值),而非后验分布。

calibrate 目前仅适用于 DSSAT v4.8.6 的玉米样例处理,且氮素关闭;自由运行的逐日模型为这些处理读取的表格不随项目分发。氮素使 DSSAT 产量变化超过 5 % 的处理会被拒绝。

05可组合6 帧

一个过程是带有声明签名的纯函数;换掉一个,同样的检查照常运行

  1. 5.1一个过程是声明了读写字段的纯函数。三道检查约束的是作者,而不是数值内核:写代码时的 AST 静态检查(AJ001–AJ012、AJ020–AJ021)、运行时对声明写入的核对(AGRI_JAX_CHECK=1),以及注册时的一致性测试包。每个系数都带有名称、单位、含义与出处。
  2. 5.2第一条守则,纯函数:读取的一切都是参数,改动的一切都由返回值给出。两个生长季同时写入同一个格子就是冲突,所以状态里每个生长季占一行。
  3. 5.3第二条守则,用 where 分支:同一天里各个生长季处在不同的生育阶段,所以两个分支都要计算,每一行各取自己的那个。两个分支都必须保持有限,否则梯度会变成 NaN。
  4. 5.4第三条守则,过程代码中不对土层、日期或样本写循环。沿土壤剖面的递推只写一次,怎样运行由运行时决定:在 CPU 上是循环,在 GPU 上是展开(见第三幕)。
  5. 5.5只需一行,即可将这一天的土面蒸发由 Ritchie 换为 SALUS。替换后的过程在运行前,要通过对条目声明的核对以及一致性关卡。
  6. 5.6换入带来什么变化:65 个运行各用自身方法与另一种方法模拟一次,全季土面蒸发的中位数变化为 +26 % 与 −14 %,籽粒产量的中位数变化为 −0.07 % 与 −0.12 %,范围 −27.7 % … +16.1 %。每个换入后的运行中,水量账都闭合到 ≤ 5.9e-14 mm。每种方法按自身运行时都能复现 dscsm048;换入后的运行则是另一个模型。

换入的具体数字见“实测”一节的表格。examples/swap_soil_evaporation.py 无需数据,即可在一个合成生长季上运行这一替换;docs/swapping_a_process.md 与 docs/tutorial_new_process.md 分别说明替换后的检查,以及从零写一个过程。

06实测与可重跑15 行

凡标注“实测”的数字,都可以重跑

每一行给出条件,以及用什么重跑。集成测试需要 DSSAT-CSM 程序与自由运行的输入表,二者均不随项目分发(见 README.zh.md);单元测试层不需要数据。图由 scripts/showcase/ 依据这些运行的结果文件绘制。教程笔记本可在 Colab 中运行:在 Colab 中打开。

指标数值条件重跑方式状态
籽粒产量对 DSSAT-CSM 的偏差,59 个有籽粒生长季最大 1.5 %
中位数 4.0e-5
65 个整季自由运行(58 个 DSSAT 玉米样例处理,7 个 CA-TPA 生长季),氮素关闭,CPU 上 float64;验收上限 2 %;2026年9月30日tests/integration/test_day_dssat486_free.py(--runslow)实测
出苗、吐丝与成熟日期65 个全部一致同上运行;生育阶段与叶数逐日一致同一测试实测
LAI 的 RMSE · 剖面土壤水分的 RMSE · 每日水量账最大残差0.0061 · 0.33 mm · 6.6e-14 mm同上 65 个运行的最大值(中位数 0.0029、0.29 mm、3.6e-14 mm);DSSAT 的土壤水分取整毫米输出同一测试实测
XTRACT 吸水 · 潜在蒸散发 · 土壤反照率,逐日检验1.03 · 4.7 · 4.5 个 REAL*4 单位在 DSSAT 自身输入上;58 个运行(10 050 天)与 65 个运行test_day_dssat486_free.py::test_xtract_albedo_and_petpt_on_the_dumps实测
仅运行 CERES-Maize,由 DSSAT 的土壤水分与蒸腾驱动LAI 0.50 %
产量 0.030 %
58 个处理;生物量 0.63 %;生育阶段逐日一致tests/integration/test_ceres_dssat.py实测
GPU float64 对 CPU float64,65 个生长季产量 1.4e-15
阶段 65 个一致
整块 H100 与 1g.10gb 切片,层循环展开;GPU 上展开对循环:产量、土壤水分、径流、排水逐位一致,65 个运行中 17 个在全部输出上逐位一致;2026年9月29日tests/integration/test_day_dssat486_free_gpu.py实测
单核 10⁵ 个生长季:DSSAT-CSM · Agri-JAX 首次运行 / 热启动 / 重复调用1426 s · 99.1 / 56.0 / 48.9 sAMD EPYC 9654 的一个绑定核,float64,向主机返回十条逐日序列;DSSAT-CSM 含逐日文件(仅汇总为 745 s);2026年9月28日;仅测一次scripts/bench/d4_jax_scaling.py(Agri-JAX 一侧)实测
DSSAT 一侧的脚本尚未公开
同上,32 核46.8 s · 20.8 / 11.3 / 2.1 s节点上的 32 核分配,任务与计时边界相同;DSSAT-CSM 仅汇总为 26.9 s同上实测
DSSAT 一侧的脚本尚未公开
同上,192 核整节点17.4 s · 20.5 / 10.9 / 0.66 s2 × AMD EPYC 9654;DSSAT-CSM 仅汇总为 17.2 s;不同进程间重复调用时间的差异最大可达 20 %同上实测
DSSAT 一侧的脚本尚未公开
同上,一块 H100(仅 Agri-JAX)77.5 / 14.4 / 0.424 s整块 H100 80GB HBM3,主机 Xeon Gold 6448Y,层循环展开(GPU 默认);循环时为 28.7 / 11.2 / 1.31 s;2026年9月29日;该主机上未运行 DSSAT-CSMscripts/bench/d4_jax_scaling.py实测
GPU 层循环展开,10⁵ 个生长季每日内核 489 → 63 个
1.31 → 0.42 s
整块 H100,float64;设备空闲 33.6 → 1.9 %;XLA 编译 19.0 → 67.4 s;2026年9月29日scripts/bench/d4_2_gpu_diag.py
tests/unit/test_execution.py
实测
籽粒总质量的一次梯度,10⁴ 个生长季展开 1.81 s
循环 5.02 s
整块 H100,float64,五个系数,逐日步置于 jax.checkpoint 之下;XLA 编译 315.6 s 对 64.2 s;2026年9月29日scripts/bench/d4_grad_compile.py实测
calibrate,UFGA8201 处理 4,处理 6 留出1.015 → 0.0100
35.3 s
rorqual 的 32 个 CPU 核,默认设置;留出处理 1.046 → 0.0239;以写出的行运行 DSSAT,产量与 Agri-JAX 相差在 2.9e-4 以内,日期一致;2026年9月30日docs/calibration.md
tests/integration/test_calib_workflow_dssat.py
实测
标定所得 .CUL 行在 DSSAT-CSM 中重跑 · 联合 CMA-ES 对分阶段方案 · G2–G3 等高线22 / 22 · 225 对 212(共 264 次)· 41 × 41 网格往返检验:22 个运行,日期一致,产量偏差在 0.1 % 以内。合成恢复:264 次拟合,192 核节点。等高线:其余系数固定,24 次重新标定;2026年9月28日scripts/showcase/fig_calibration.py(绘图)实测
研究脚本尚未公开
替换这一天的土面蒸发方法产量中位数变化 −0.07 % 与 −0.12 %65 个运行,各用自身方法与另一种方法;见下表;2026年9月30日examples/swap_soil_evaporation.py
tests/integration/test_day_dssat486_swap.py
实测

替换土面蒸发方法后有什么变化

替换运行数全季土面蒸发
变化中位数
籽粒产量
中位数 [范围]
水量账最大残差
自身 / 替换后,mm
自身方法对 DSSAT 产量
最大相对差
Ritchie → SALUS(MESEV R → S)39(其中 33 个有产量)+26 %−0.07 % [−27.7 %, +6.9 %]6.6e-14 / 5.9e-141.5 %
SALUS → Ritchie(MESEV S → R)26(其中 26 个有产量)−14 %−0.12 % [−3.2 %, +16.1 %]3.6e-14 / 3.2e-140.019 %