SWATGenXSWATGenX
Watershed ExplorerExample modelsCloud calibrationDocsAccess

SWAT+ production engine

The SWAT+ engine we run in production

SWATGenX runs our fork at ship/v1.0-48 — a pinned SWAT+ build (NetCDF backend, print-filtering, and two engine fixes) unified with opt-in multi-core, PFAS, and MODFLOW 6 — deployed only after a ship-gate certification proves it output-identical on plain models.

Pinned per release: our fork at ship/v1.0-48 (deployed 2026-08-01; commit 6520940 for auditors). Ladder measured on Peace River HUC-8, 94,303 HRUs.

Stock → production wall time94k HRUs · 90 days
0125250375500wall (s)462sStock5ccf6f0414sNetCDF+filter768f1d1227sTwo fixes247e95b2.0× faster core341×smaller output695 MB → 2.0 MBMeasured: unified6520940≤ 1e-5 certifiedon plain models+ opt-in multi-core,PFAS, MODFLOW 6
Byte-identical results across all rungs. The unified rung (fork@6520940) is the build these numbers were measured on; production tracks it forward under the ship gate. Multi-core scaling is on the parallel-engine page.
  • Current pin: our fork at ship/v1.0-48
  • 341× smaller output vs stock
  • ~2× faster engine core vs stock
  • Ship-gate certified ≤ 1e-5 on plain models

A recurring question is which exact SWAT+ binary builds SWATGenX models, and how it differs from the stock distribution. SWATGenX runs our fork at ship/v1.0-48 — pinned per release — and every speed/size claim on this page is measured against the stock original.

It is an overview, not a re-derivation. The detailed evidence for each contribution lives on its own deep-dive page; here we show the cumulative stock-to-production ladder and a changelog of every contribution and its state — the four output/performance layers are each an open upstream PR, and the multi-core, PFAS, and MODFLOW 6 layers live on the open fork.

The current production build is our fork at ship/v1.0-48 (deployed 2026-08-01; commit 6520940 for auditors): the measured fast engine core plus three opt-in capabilities — shared-memory OpenMP parallelism, PFAS fate-and-transport, and a daily two-way MODFLOW 6 coupling. All three are inert at the plain-model serial default, and a pre-production ship gate certifies each swap output-identical to the previous engine on ordinary models before it deploys.

Production engine pin

SWATGenX runs our fork at ship/v1.0-48.

Key takeaways

  • SWATGenX runs our fork at ship/v1.0-48 in production — pinned per release, deployed 2026-08-01 (commit rafiei-vahid/swatplus@6520940 for auditors). Parallel execution is certified byte-identical to a single-threaded run of the same build in 18 of 18 runs — three trials at each of 2, 4 and 8 threads, in both parallel modes, over 935,130 compared values apiece — on a fixture that reproduces the defect 5/5 on the pre-fix binary.
  • NetCDF output + the channel_sd print-filter cut output size 341× (695 MB → 2.0 MB) versus stock.
  • The two engine fixes then attack compute: the measured engine core runs ~2.0× faster than stock, with byte-identical results — and the unified build is ship-gate certified output-equivalent to that core on plain models (≤ 1e-5).
  • The unified engine adds opt-in OpenMP parallelism, PFAS transport, and a MODFLOW 6 coupling — all inert at the plain-model serial default, all deployed today.
ship/v1.0-48
production fork tag
341×
smaller output vs stock
2.0× faster
wall time vs stock
In production
deployed engine
1

Motivation

What SWATGenX runs, and how far it is from stock SWAT+

"Production" should never be a vague word. SWATGenX runs our fork at ship/v1.0-48 — pinned per release — and it differs from the stock distribution in ways we can point to and measure. This page pins down exactly what we run and how far it is from the original.

It is the changelog and the integrator: a stock → fork-production ladder ending at the current unified engine, plus a table of every contribution and its state. The detailed proof for each lives on its own deep-dive page — here we show the cumulative effect, anchored to commits.

2

Methods

Every engine, pinned to a commit

Four engines are pinned for comparison. The stock baseline is swat-model/swatplus@5ccf6f0. Two fork rungs were each production in turn: 768f1d1 (NetCDF backend + channel_sd print-filter) and 247e95b (the same plus the two engine fixes). Current production is our fork at ship/v1.0-48 (commit rafiei-vahid/swatplus@6520940, deployed 2026-08-01): the 247e95b core consolidated with opt-in OpenMP parallelism (HRU land phase + routing wavefront), PFAS fate-and-transport, and a daily two-way MODFLOW 6 coupling. At its serial default all of that is inert, so a plain model runs exactly as before.

The three measured rungs were run on the same basin and window (Peace River HUC-8 (03100101) — 94,303 HRUs, 90 simulated days, ifx -O3 -ipo), each in its own native output mode — stock writes formatted-text channel_sd for all channels; the fork builds write gauge-filtered NetCDF — so the ladder reflects how each engine would actually be used, not an artificial common setting. The unified rung is deliberately not re-timed here: instead of a new benchmark, it carries a certification.

Before the 6520940 swap the candidate passed the full pre-production ship gate (scripts/ship_gate/gate.py): 75 checks PASS, 0 FAIL. Tier 1 on three plain benchmark models (M_09471300, MID_03100205, and MYAKKA_FERT_03100102 which runs scheduled fertilizer operations): backward-compatibility against the previous production engine byte-clean at exactly 0.00e+00, and parallel-vs-serial byte-identity at EXACT equality (0 differing cells over every output file) in BOTH parallel modes (HRU-parallel and full routing wavefront), at 2 and 4 threads, with 3 repeat trials per check — repeats included because a data race is probabilistic and a single clean run is not evidence. Tier 2 on the coupled SWAT+/MODFLOW-6 PFAS model: flow, nutrients and PFAS byte-clean against the golden reference, MODFLOW mass-balance discrepancy -0%, and coupled byte-identity for both parallel modes at 2 and 4 threads. Log: GenXAppData/ship_gate/runs/2026-08-01_v1.0-48-g6520940_vs_v1.0-45-g6423104_SHIP.log

RoleRepo @ commitWhat it is
Stockswat-model/swatplus@5ccf6f0stock SWAT+ (upstream/main) — formatted-text output, no filter
First fork productionrafiei-vahid/swatplus@768f1d1first fork production — NetCDF backend + channel_sd print-filter (deployed until 2026-06-06)
Second fork productionrafiei-vahid/swatplus@247e95bsecond fork production — NetCDF + print-filter + the two engine fixes (deployed 2026-06-06 → 2026-06-28)
Current productionrafiei-vahid/swatplus@6520940current production — unified engine (NetCDF + print-filter core, opt-in OpenMP parallelism, PFAS fate-and-transport, MODFLOW 6 coupling). Parallel execution is certified byte-identical to a single-threaded run OF THE SAME BUILD in 18 of 18 runs — three trials at each of 2, 4 and 8 threads, in both parallel modes, over 935,130 compared values apiece — on a 777-HRU fixture that activates scheduled fertilizer and pesticide operations, tile drainage and PFAS transport, and that reproduces the defect 5/5 on the pre-fix binary. "Of the same build" is load-bearing: recompiling changes results at floating-point level, so a rebuild is not the comparison being certified. Deployed 2026-08-01; engine rev 62.0.0-81-g6520940, fork tag ship/v1.0-48
  • Baseline: swat-model/swatplus@5ccf6f0 (stock).
  • Fork productions, in order: 768f1d1 (NetCDF + filter) → 247e95b (+ two engine fixes).
  • Current production (deployed 2026-08-01): our fork at ship/v1.0-48 — unified engine, serial default, opt-in parallelism/PFAS/MF6.
  • Each measured number on this page is sourced from the release manifest, not hand-edited.
3

Results and discussion

Stock → fork productions → current unified engine

Peace River HUC-8 (03100101) — 94,303 HRUs · 90 simulated days.

Figure 1. Wall time and output size across the three measured rungs on Peace River HUC-8 (03100101) — 94,303 HRUs (90 simulated days). NetCDF + filtering crushed size; the two fixes crushed runtime. The current unified engine (6520940) is certified output-equivalent to the fastest measured rung on plain models, so it inherits these numbers at its serial default.

Table 1. Stock → fork productions → current unified engine, each pinned to a commit, with wall time, output size, and ratios versus stock for the measured rungs.

StageCommitWall (s)Outputvs stock (wall)vs stock (size)State
Stock5ccf6f0462695.10 MB1.0× (baseline)1.0× (baseline)upstream original
NetCDF + print-filter768f1d14142.04 MB1.1×341× smallerfirst fork production (superseded 2026-06-06)
Two engine fixes247e95b2272.04 MB2.0×341× smallersecond fork production (superseded 2026-06-28); measured core of the current engine
Unified engine6520940not re-timedsame filtered NetCDFdeployed — current (2026-08-01)

Unified engine (6520940): Not re-timed on this ladder. The ship gate certifies OUTPUT equivalence (worst-relative ≤ 1e-5) to the 247e95b rung on plain models at the serial default — that is a correctness result, not a wall-time one. The unified build is compiled with OpenMP, and an OpenMP build costs 1.20–1.24× at one thread against a serial-only build of the same core (measured twice on AWS c8a), so its serial wall time is not claimed to match the 247e95b rung. Opt-in multi-core scaling is measured separately on the parallel-engine page.

The contribution families move different axes. NetCDF + print-filtering (stock → 768f1d1) cut output ~341× (695 MB → 2.0 MB) while wall time changed only ~1.1× — because once output is small, the bottleneck is compute, not I/O. The two engine fixes (768f1d1 → 247e95b) then attack the compute: the same run drops to 227 s, ~2.0× faster than stock with byte-identical results. The unified engine (6520940) keeps that measured core — certified output-equivalent on plain models (≤ 1e-5) — and adds the opt-in capabilities: multi-core scaling (measured on the parallel-engine page), PFAS transport, and the MODFLOW 6 coupling.

Contributions and their state

Table 2. Every engine contribution: the axis it moves, its headline effect, its state (output/perf contributions have open upstream PRs; the parallel/PFAS/MF6 layers live on the open fork), and a link to its deep-dive evidence.

ContributionAxisHeadlineStateUpstream PRDetails
NetCDF output backendoutput formatenables compact NetCDF outputin production; upstream PR open#213runtime benchmark
channel_sd print-filteroutput scopegauge-only channel_sd → 341× smallerin production; upstream PR open#214runtime benchmark
hru_read O(1) name indexruntime (startup)string name-matching 75 → 7 sin production; upstream PR open#219performance profiling
varinit per-row resetruntime (daily loop)array zeroing 28 → 2 sin production; upstream PR open#220performance profiling
OpenMP parallelism (HRU land phase + routing wavefront)runtime (multi-core)5.33× at 24 threads on a 32-core node; byte-identical at 1 threadin production (opt-in; serial default); fork mainfork onlyparallel engine
PFAS fate-and-transportnew physicswatershed-scale PFAS transport in SWAT+ (Freundlich sorption)in production (inert unless configured); fork mainfork onlyPFAS fate & transport
MODFLOW 6 couplingnew physicsdaily two-way recharge/baseflow exchange with MODFLOW 6in production (inert without mf6 config); fork mainfork onlySWAT+ × MODFLOW 6
4

Conclusion

  • Production is pinned per release — currently rafiei-vahid/swatplus@6520940 (deployed 2026-08-01), the unified engine: the measured 247e95b core plus opt-in OpenMP parallelism, PFAS fate-and-transport, and a MODFLOW 6 coupling, all inert at the plain-model default.
  • Versus stock on a 94k-HRU basin, the measured engine core writes ~341× smaller output and runs ~2.0× faster, with byte-identical results; the unified build is ship-gate certified output-equivalent (≤ 1e-5) to that core on plain models.
  • Output size and runtime are independent axes: NetCDF + filtering won on size, the two fixes won on speed, and both are in the shipped engine. The four output/perf contributions each have an open upstream PR against swat-model/swatplus (#213/#214/#219/#220); the parallelism, PFAS, and MODFLOW 6 layers live on the open fork's main branch and are documented on their own pages.

FAQ

Which SWAT+ engine does SWATGenX actually run in production?

SWATGenX runs our fork at ship/v1.0-48 — the unified engine deployed 2026-08-01 (commit rafiei-vahid/swatplus@6520940 for auditors), whose parallel execution is certified byte-identical to the serial engine. Its engine core is rafiei-vahid/swatplus@247e95b (built on the stock swat-model/swatplus baseline plus a NetCDF output backend, channel_sd print-filtering, and two engine fixes, PRs #219/#220), consolidated with three opt-in capabilities: OpenMP parallelism (multi-core HRU land phase + wavefront routing), PFAS fate-and-transport, and a daily two-way MODFLOW 6 coupling. Production is pinned per release, not a moving label — and at the plain-model serial default the parallel/PFAS/MF6 code is inert, so an ordinary SWAT+ build runs exactly as the 247e95b core did.

How does production compare to stock SWAT+?

On a 3-month Peace River run (94,303 HRUs), stock writes a 695 MB channel_sd text file in 462 s; the measured engine core writes a 2.0 MB filtered NetCDF file in 227 s — output size ~341× smaller and wall time ~2.0× faster, with byte-identical results. The current unified build (6520940) is ship-gate certified output-equivalent to that core on plain models (worst-relative ≤ 1e-5), so it carries the same numbers at its serial default; its opt-in multi-core scaling (up to ~7.1× end-to-end) is measured on the parallel-engine page.

How do you know the unified engine is safe for ordinary models?

Every engine binary passes a pre-production ship gate before it can replace the deployed one. Tier 1 regresses the candidate against the live production engine on plain benchmark models — flow and nutrient worst-relative differences must be ≤ 1e-5 (compiler-noise band) — and separately requires every parallel run to be byte-identical to a serial run of the same binary: exact equality across every variable of every output file, at two thread counts, in both parallel modes, repeated three times per check because a data race is probabilistic and one clean run is not evidence. Tier 2 validates the coupling and PFAS transport against a committed golden on the Rogue SWAT+/MODFLOW 6 model, with MODFLOW mass-balance discrepancy < 1%. Tier 3 handles deploy safety: it refuses to swap while any model build or calibration is in flight, backs up the previous binary, smoke-tests, and auto-rolls-back on failure. The current 6520940 engine passed all three: 75 checks, zero failures, on 2026-08-01.

Are the engine contributions upstream in official SWAT+?

The four output/performance contributions are each open as an independent pull request against swat-model/swatplus — NetCDF backend (#213), channel_sd print-filter (#214), hru_read O(1) name lookup (#219), and varinit per-row reset (#220) — proposed but not yet merged into the official release, so SWATGenX runs them from the pinned fork today. The parallelism, PFAS, and MODFLOW 6 layers live on the open fork’s main branch (github.com/rafiei-vahid/swatplus) and are documented on their own pages.

Where do the detailed numbers live?

Each contribution has its own deep-dive page that owns its evidence: the performance-profiling page for the two engine fixes, the runtime-benchmark page for output format and print scope, and the parallel-engine page for the multi-core scaling. This page is the changelog/overview that links to them.

Next steps

Build a model of your watershed
SWAT+ parallel engine (multi-core OpenMP)
Hydrology calibration methods

Last updated 2026-07-13.