REVIEW 2 major objections 5 minor 1 cited by
C codegen considered unnecessary: go directly to binary, do not pass C. Compilation of Julia code for deployment in model-based engineering
T0 review · 2 major / 5 minor · reviewed 2026-08-09 · deepseek-v4-flash
Pith's one-line read Julia's trimming compiler turns equation-based models and Julia libraries directly into small standalone binaries and C-callable shared libraries, making C code generation unnecessary for many model-based engineering deployments.
desk verdict A credible demo of compiling Julia/MTK straight to binaries, but the 'real-time' claim outruns the evidence. read the letter →
The pith
A machine-rendered reading of the paper's core claim, the machinery that carries it, and where it could break.
The reading
What carries the argument
The load-bearing mechanism is Julia's trimming mode, exposed through the juliac compiler tool: an ahead-of-time static analysis over a list of user-declared entry points that flags any call site too dynamic for specialization, prunes loaded code not reachable from an entry point, and emits architecture-specific machine code via LLVM. The produced binaries still link to the Julia runtime—currently adding about 48 MB—but the application code itself drops to a few megabytes. The workflow additionally relies on compiler extension tools that verify statically sized arrays and the absence of heap allocations or runtime dispatch during the filtering operation.
What would settle it
Hooking the compiled state estimator into an actual loop on the Raspberry Pi with a fixed sample period and measuring the worst-case execution time, or checking for any heap allocation during a cycle, would settle the real-time claim: if worst-case latency exceeds the filter's sample period, or if allocations or dynamic dispatch appear, the paper's real-time deployment claim as stated is not supported.
Extended reading notes
Core claim
The central discovery is that a high-level language's own compiler pipeline can replace the C-code generation step that model-based engineering workflows normally insert between a symbolic model and a deployed binary. Julia's trimming mode statically analyzes user-declared entry points, requires each call site to have a bounded set of targets, prunes unreachable and development-only code, and emits a small, specialized binary through LLVM. The concrete evidence is a state estimator for a continuously stirred tank reactor—model generated in ModelingToolkit, filtering implemented with a preexisting Julia package, all arrays statically sized—compiled to a 3.5 MB executable that performs trajectory filtering and log-likelihood computation, and a DiscretePIDs library compiled to a 1.7 MB shared object with a C-callable interface. The authors read this as a counterexample to the claim that a productive high-level language must be rewritten in C for real-time estimation and control.
Load-bearing premise
The paper assumes that running the compiled estimator over saved input and measurement files, on a desktop and on a Raspberry Pi, is a valid stand-in for real-time control; the demonstrated main function performs batch trajectory filtering and computes a log-likelihood rather than closing a control loop with guaranteed sample deadlines.
Editorial extensions
If this is right
- Engineers can go from an equation-based model to a deployed binary without writing or generating C: the CSTR/UKF estimator compiled with juliac produced a 3.5 MB executable that ran the filtering job on a Raspberry Pi.
- Short-lived or latency-sensitive Julia workloads gain from avoiding JIT startup: the same filtering job completed in 26.667 ms versus 2.484 s for the standard execution model, roughly a 93x wall-clock speedup in this setup.
- Julia packages can be shipped as C-callable shared libraries: the PID library compiled to a 1.7 MB shared object whose entry points were callable from a C program via the standard dynamic-library interface.
- Because the source is compiled from native Julia rather than generated C, the usual C-codegen restrictions on variable-sized arrays, flexible data structures, operator overloading, and arrays of objects do not apply to this deployment path.
- Cross-compilation is already available in principle through emulation, so a developer on one operating system and architecture can produce binaries for another target without moving the build to the device.
Reading between the lines
- Editorial inference: a natural next test is closing the loop—attach the compiled estimator to a live sensor stream with a fixed sample period and show that worst-case cycle time stays under the period; the paper's batch log-likelihood demo does not yet show this.
- Editorial inference: if trimming becomes a stable feature, the same pipeline could replace the generated-C layers in functional mock-up unit exports, since ModelingToolkit already has a path for generating callable dynamics and the paper names FMU deployment as a downstream target.
- Editorial inference: a sharper benchmark would separate startup time from sustained throughput; the 93x figure mostly reflects avoiding JIT compilation, so measurements of steady-state per-call cost would clarify what embedded users actually gain.
Editorial analysis
A structured set of objections, weighed in public.
Referee Report
Summary. The paper demonstrates an alternative to the standard C-code-generation workflow in model-based engineering: using Julia's new "trimming" ahead-of-time compiler mode via the juliac tool, the authors compile a ModelingToolkit-based unscented Kalman filter for a CSTR into a 3.5 MB standalone executable and the DiscretePIDs.jl package into a 1.7 MB C-callable shared library, with all code and repositories linked. They report a roughly 93x wall-clock speedup of the compiled estimator over a fresh Julia process under the standard JIT execution model, attribute it to ahead-of-time compilation, and discuss trimming, emulation-based cross-compilation, and current limitations including the Julia runtime dependency and lack of bare-metal support. The paper concludes that recent compiler developments make direct-to-binary deployment of Julia-based models a viable route where C code generation is not strictly required.
Significance. The core capability claim — that equation-based Julia/ModelingToolkit code can be compiled directly to small native executables and shared libraries without C as an intermediate — is credible, directly demonstrated, and supported by linked repositories and CI-verified properties (AllocCheck/JET-based no-allocation and no-dynamic-dispatch checks for the UKF and PID code). This is a timely and useful existence proof for the model-based-engineering community, and the honest disclosure of limitations (prerelease Julia, roughly 48 MB runtime dependency, OS requirement, no bare-metal/RTOS support) strengthens its credibility. The weaker point is the advertised scope: the evidence does not establish "real-time" operation in the engineering sense, since the estimator runs as a batch process over pre-recorded files and no loop-rate, latency, or deadline data are reported. With re-scoped claims or additional timing evidence the paper would be a solid contribution; as written, the headline claim overreaches the measurements.
major comments (2)
- [Abstract; Sections III-A3, III-A4, III-B] The claim that Julia-based models can be compiled and deployed "for real-time model-based estimation and control" is not supported by the evidence. The estimator's main function reads complete input and measurement data files and calls forward_trajectory (Section III-A3), which is batch filtering over a recorded trajectory rather than a fixed-sample-rate or deadline-driven loop, and no loop rate, latency, jitter, worst-case execution time, or missed-deadline statistics are reported. The 93x speedup in Section III-A4 compares the compiled executable with a fresh `julia --project juliac_demo.jl` process, so it conflates the avoidance of package loading and JIT warmup with sustained execution speed, and Section III-B reports no timing at all for the shared library. Section IV's own limitations (Julia runtime required, traditional OS required, no bare-metal or RTOS support) further narrow what "real-time deployment" can mean here. The authors should either add per-iteration timing at a stated control rate, or replace "real-time" in the abstract and introduction with scoped language such as "compiled deployment for time-critical estimation and control" and report the components of the 93x factor separately.
- [Section III-A4] The headline 93x factor rests on a single wall-clock measurement with no hardware specification, no repeated runs or dispersion statistics, and no split between startup (package loading and JIT compilation) and steady-state filtering time; the footnote saying the Raspberry Pi runs the binary "about 4x slower" is likewise unanchored, with no trajectory length or runtime breakdown. Since this is the paper's main quantitative evidence of viability, the benchmark should report the hardware, number of runs, medians, trajectory length, and a decomposition of total runtime into initialization versus computation, so that readers can judge sustained per-step performance rather than startup avoidance.
minor comments (5)
- [Section II-A] The comparison with PackageCompiler.jl is qualitative; reporting the binary size produced by PackageCompiler for the same example would substantiate the claim of a "dramatic size reduction" and give readers a concrete baseline.
- [Section IV] The dependence on an unreleased Julia v1.12 prerelease is disclosed, but reproducibility would be improved by stating the exact Julia version or commit and the juliac revision used for all reported measurements.
- [Abstract; Section III] The paper never defines "real-time"; the authors should state the intended sense (hard real-time, soft real-time, or simply a periodic loop), since the evidentiary requirements differ substantially.
- [Section III-B] The C demo would be strengthened by a correctness check of the PID outputs rather than only printed values, and by linking the sample-time parameter Ts to an actual loop period in the demonstration.
- [Section I, footnote 5] The qualification that C-code generation may be required by regulation, safety standards, or target-platform constraints is important enough to be reflected in the abstract or conclusion, so that the paper's scope is not overread.
Circularity Check
No significant circularity: the central claim is a direct tool demonstration with inspectable code artifacts and measurements; the weak real-time evidence is a scope/validity concern, not a circular derivation.
full rationale
The paper makes a capability claim: that recent Julia compiler developments allow compiling ModelingToolkit- and Julia-based code directly to binaries and shared libraries without C code generation. This claim is supported by concrete case studies, code listings, repository links, binary size measurements, and a benchmark comparing the compiled executable to the standard Julia execution model. There is no equation-level derivation in the paper that reduces to fitted parameters or to the model's own output, so self-definitional and fitted-input-as-prediction circularity are absent. The cited repositories [2] and [3] are authored by the paper's authors, but they are used as locations of the demonstrated artifacts, not as authority for the paper's conclusion; the artifacts are directly inspectable and the benchmark is reproducible in principle. The 'real-time' wording in the abstract is broader than the demonstrated evidence: case study 1 processes a batch of recorded data from files and computes a log-likelihood using forward_trajectory, and the 93x speedup compares against a fresh Julia process that includes JIT compilation and package loading, which conflates startup avoidance with sustained execution speed. However, overstating the real-time scope is a correctness and evidence-validity concern, not a circularity concern, because the claim does not derive its own premise from its conclusion. No self-citation chain is used to forbid alternatives or to justify a uniqueness claim. Therefore the appropriate circularity score is 0.
Assumptions & free parameters
assumptions (3)
- domain assumption Julia's trimming mode correctly identifies and emits only sufficiently specialized code, so the generated binary is free of runtime dispatch and dynamic allocations for the demonstrated examples.
- domain assumption The Julia runtime, about 48 MB, and a conventional operating system are acceptable deployment constraints for the targeted model-based engineering applications.
- domain assumption A benchmark measuring wall-clock runtime over a pre-recorded data trajectory is a valid proxy for real-time control suitability.
Cite this review
Pith. "Pith review of C codegen considered unnecessary: go directly to binary, do not pass C. Compilation of Julia code for deployment in model-based engineering." pith.science (2026). https://pith.science/paper/M35OX56R
@misc{pith2026250201128,
author = {Pith},
title = {Pith review of: C codegen considered unnecessary: go directly to binary, do not pass C. Compilation of Julia code for deployment in model-based engineering},
year = {2026},
howpublished = {\url{https://pith.science/paper/M35OX56R}},
note = {Machine review of arXiv:2502.01128}
}
read the original abstract
Since time immemorial an old adage has always seemed to ring true: you cannot use a high-level productive programming language like Python or R for real-time control and embedded-systems programming, you must rewrite your program in C. We present a counterexample to this mantra by demonstrating how recent compiler developments in the Julia programming language allow users of Julia and the equation-based modeling language ModelingToolkit to compile and deploy binaries for real-time model-based estimation and control. Contrary to the approach taken by a majority of modeling and simulation tools, we do not generate C code, and instead demonstrate how we may use the native Julia code-generation pipeline through LLVM to compile architecture-specific binaries from high-level code. This approach avoids many of the restrictions typically placed on high-level languages to enable C-code generation. As case studies, we include a nonlinear state estimator derived from an equation-based model which is compiled into a program that performs state estimation for deployment onto a Raspberry Pi, as well as a PID controller library implemented in Julia and compiled into a shared library callable from a C program.
Forward citations
Cited by 1 Pith paper
-
Accelerating Bidiagonalization of Banded Matrices through Memory-Aware Bulge-Chasing on GPUs
A memory-aware GPU bulge-chasing algorithm reduces banded matrices to bidiagonal form, achieving >100x speedups over CPU libraries at 32k sizes.
Reference graph
Works this paper leans on
-
[1]
J. Bezanson, A. Edelman, S. Karpinski, and V. B. Shah, ``Julia: A fresh approach to numerical computing,'' SIAM review, vol. 59, no. 1, pp. 65--98, 2017
work page 2017
-
[2]
Bagge Carlson, ``static\_kalman,'' https://github.com/baggepinnen/static_kalman
F. Bagge Carlson, ``static\_kalman,'' https://github.com/baggepinnen/static_kalman
-
[3]
------, `` DiscretePIDs.jl ,'' https://github.com/JuliaControl/DiscretePIDs.jl
-
[4]
4" FUNCTION default.is.dash.repeated.names #1 FUNCTION default.name.format.string
11em plus .33em minus .07em @technote 4000 4000 100 4000 4000 500 `\.=1000 = #1 #1 #1 0pt [0pt][0pt] #1 * \| ** #1 \@IEEEauthorblockNstyle \@IEEEauthorblockAstyle \@IEEEauthordefaulttextstyle \@IEEEauthorblockconfadjspace -0.25em \@IEEEauthorblockNtopspace 0.0ex \@IEEEauthorblockAtopspace 0.0ex \@IEEEauthorblockNinterlinespace 2.6ex \@IEEEauthorblockAinte...
work page 2003
-
[5]
write newline
" write newline "" initialize.prev.this.status FUNCTION begin.bib preamble empty 'skip preamble write newline if " thebibliography " longest.label * " " * write newline " [1] #1 " write newline " url@rmstyle " write newline " " write newline " [2] #2 " write newline " =0pt " write newline " " ALTinterwordstretchfactor * " " * write newline " = 2 plus " wr...
Reviewed August 9, 2026 · model on record in the stance chip above.
Discussion (0). Continue with ORCID to comment.