Repository navigation
Expand file tree
/
Copy pathCargo.toml
More file actions
164 lines (143 loc) · 6.61 KB
/
Copy pathCargo.toml
File metadata and controls
164 lines (143 loc) · 6.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
[workspace]
resolver = "2"
members = [
"src/libsimlin",
"src/simlin-cli",
"src/simlin-engine",
"src/simlin-mcp",
"src/simlin-mcp-core",
"src/simlin-serve",
]
# Release builds optimize for speed (opt-level = 3) on every target. The wasm32
# bundle builds through the two profiles below, which inherit this one; it is
# never built with `release` directly. Measured on C-LEARN: opt-level 3 vs "z"
# is ~-30% compile and ~-41% simulate on native (see
# docs/design/engine-performance.md), and on the wasm bundle size-optimized
# codegen costs a 1.6x to 1.7x slower open-compile-run pipeline for a 0.6 MB
# smaller compressed download.
#
# `lto = true` applies to the native binaries and, through `wasm-release`, to
# the wasm bundle -- but only because src/engine/build.sh builds the latter
# with `cargo rustc --crate-type cdylib`: cargo passes `-C lto` only when every
# crate type of the target allows it, and libsimlin's rlib does not, so a plain
# `cargo build -p simlin` on any target is a non-LTO build whatever this line
# says.
[profile.release]
opt-level = 3
lto = true
panic = "abort"
strip = true
# The wasm bundle's two profiles. src/engine/build.sh is the only wasm32 build
# path and picks one of these with `--profile`.
#
# `wasm-release` is what ships: the npm packages, the GAE deploy, and the
# notebook widget's wheel assets. On top of `release` it sets
# `codegen-units = 1`, so LLVM sees each crate whole before fat LTO merges
# them. Measured on C-LEARN v77 through src/engine/bench/clearn-alloc.mjs
# (browser bundle after `wasm-opt -O3`, LTM on, node 22 / V8 12.4 and node 24
# / V8 13.6): against thin LTO with parallel codegen, the cheapest alternative,
# the compile stage is 1.05x to 1.07x slower there and the LTM run stage 1.21x
# to 1.23x slower on V8 13.6 (within 2% either way on V8 12.4); fat LTO with
# parallel codegen and thin LTO with one unit both land at 1.25x on that run
# stage. The two settings only pay as a pair -- relaxing either one alone
# forfeits the whole V8 13.6 run-stage gain for a modest build-time saving --
# so change them together or not at all. The bundle is also 5% smaller raw
# than with parallel codegen (9.36 MB to 9.92 MB after wasm-opt).
#
# Its price is build time. Under `codegen-units = 1` LLVM runs single-threaded
# on the engine crate, and fat LTO is single-threaded again after it, so an
# engine rebuild takes ~120 s on a 32-core desktop however many cores it has
# (opt-level 3 alone: 21 s; plus fat LTO: 70 s; plus one codegen unit
# instead: 95 s), and a 4-core CI runner pays several minutes per artifact.
[profile.wasm-release]
inherits = "release"
codegen-units = 1
# `wasm-gate` is what the pre-commit hook and CI's PR lanes build: build.sh
# selects it under DISABLE_WASM_OPT=1, the same knob that skips wasm-opt,
# because both halves answer the same question (is this artifact going to
# ship?). It keeps opt-level 3 but drops LTO and the single codegen unit, so an
# engine rebuild takes ~21 s instead of ~120 s. The gate's blob only has to
# pass the TypeScript tests; a local change is not going to expose an LLVM
# link-time or codegen-partitioning bug, and
# .github/workflows/wasm-opt.yml is the lane that builds `wasm-release`, runs
# wasm-opt, and executes the result under test.
[profile.wasm-gate]
inherits = "release"
lto = false
# `gates` is what the `#[ignore]`d tests run under: scripts/gates.sh, by hand
# and in CI's `gates` job (.github/workflows/ci.yaml).
#
# They are ignored because a debug build takes minutes over the model corpus,
# C-LEARN and World3, so they need optimized code -- but not the shipping
# artifact. Dropping LTO makes the build parallel (each `release` test binary
# is its own single-threaded fat-LTO link), and the checks a debug build
# carries stay on, because these are the only tests that put the largest
# models through the engine and an overflow or a failed `debug_assert!` there
# is exactly what they should catch.
[profile.gates]
inherits = "release"
lto = false
strip = false
debug-assertions = true
overflow-checks = true
[profile.bench]
debug = true
strip = false
# Optimize a few hot DEPENDENCIES in dev/test builds. Workspace crates stay at
# opt-level 0 (fast incremental rebuilds); these are external crates that
# rarely recompile but sit on test-suite critical paths, where debug-build
# slowdown is 10-30x:
# - serde_json: the VDF parity harness decodes a multi-megabyte
# --extract-json payload (with float_roundtrip) on every `cargo test`.
# - wasm-interpreter/checked: every wasmgen parity test executes an emitted
# blob under this pure-Rust interpreter.
# - the resvg rasterization stack: the `diagram::render_png` tests rasterize
# a diagram through resvg, and unoptimized SVG filter code dominates them
# (~80% of the slowest one is `resvg::filter::morphology::apply`, per
# `perf`, with the un-inlined `u8::max` inside it alone at ~35%). Pinning
# the stack takes those 16 tests from 2.52s to 0.33s and drops the engine's
# lib-test binary below its previous one-test parallel floor.
# - salsa/hashbrown/indexmap: the incremental compilation substrate. Every
# model any test compiles goes through salsa's query engine and its
# indexmap-backed dependency edges, so this is the one pin that is spread
# across the whole suite rather than concentrated in a few tests: it cuts
# ~17% of BOTH engine test binaries' CPU. Note this `hashbrown` is the
# standalone crate behind indexmap and salsa, not the copy vendored into
# std, so `std::collections::HashMap` is unaffected.
#
# The asymmetry that makes these worth it: a dependency is not recompiled by an
# edit to a workspace crate, so a pin costs one rebuild of that dependency (and
# whatever sits above it) and then nothing at all on the edit-compile-test loop.
# Measured on the render stack: no change to a cold `cargo test -p simlin-engine
# --no-run` (61.3s vs 58.7s, inside run-to-run noise). Pinning a WORKSPACE crate
# is a different trade and is deliberately not done here.
[profile.dev.package.serde_json]
opt-level = 3
[profile.dev.package.wasm-interpreter]
opt-level = 3
[profile.dev.package.checked]
opt-level = 3
[profile.dev.package.resvg]
opt-level = 3
[profile.dev.package.usvg]
opt-level = 3
[profile.dev.package.tiny-skia]
opt-level = 3
[profile.dev.package.tiny-skia-path]
opt-level = 3
[profile.dev.package.png]
opt-level = 3
[profile.dev.package.rustybuzz]
opt-level = 3
[profile.dev.package.ttf-parser]
opt-level = 3
[profile.dev.package.fontdb]
opt-level = 3
[profile.dev.package.svgtypes]
opt-level = 3
[profile.dev.package.salsa]
opt-level = 3
[profile.dev.package.hashbrown]
opt-level = 3
[profile.dev.package.indexmap]
opt-level = 3