-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile.toml
More file actions
379 lines (343 loc) · 16.7 KB
/
Copy pathMakefile.toml
File metadata and controls
379 lines (343 loc) · 16.7 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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# cargo-make configuration for ariadnetor
# Usage: cargo make <task>
# Install: cargo install cargo-make
#
# What earns a task: a command is registered when it is long, composite,
# or has non-obvious / order-sensitive flags; when it must be
# discoverable; or when it has a canonical form that must not drift
# run-to-run. Short commands whose flags are routinely varied stay ad hoc
# (a fixed task there only removes flexibility). Genuinely ad-hoc QA
# tools that sit outside the gate (semver-checks) are listed in
# CONTRIBUTING.md rather than registered here; composite QA loops with a
# canonical form (external-types, public-api) and the mutation passes
# (mutants, mutants-arpack, mutants-hptt) earn a task: their scratch
# redirect must not drift, and the two scoped passes carry non-obvious
# flags besides.
#
# Coverage note: `gate` is the local pre-PR gate. Its clippy step runs
# with --all-targets, so it COMPILES benches; its test step runs unit +
# integration + doctests but does NOT compile benches; its doc-check step
# builds the workspace docs with rustdoc warnings denied, catching broken
# / private intra-doc links and invalid-HTML doc comments that clippy and
# doctests do not. No step in `gate` runs benchmarks — those are on demand
# via the bench* tasks.
[config]
default_to_workspace = false
# cargo-mutants copies the workspace into $TMPDIR and mutates the copy; the
# OS temp cleaner deletes that copy by age (3 days on macOS) while a long
# pass is still using it. Under target/ nothing sweeps it — but `cargo
# clean` does, which reclaims a killed run's leftovers and destroys a live
# pass's copies alike, and reaches neither if CARGO_TARGET_DIR moves cargo's
# target elsewhere. Each of the three passes below sets TMPDIR from this;
# dropping that reintroduces the failure.
[env]
MUTANTS_SCRATCH = "${CARGO_MAKE_WORKING_DIRECTORY}/target/mutants-scratch"
# ============================================================================
# Build tasks
# ============================================================================
[tasks.build]
description = "Build the whole workspace (debug)"
command = "cargo"
args = ["build", "--workspace"]
[tasks.build-release]
description = "Build the whole workspace in release mode"
command = "cargo"
args = ["build", "--workspace", "--release"]
# ============================================================================
# Test tasks
# ============================================================================
[tasks.test]
description = "Run unit + integration + doctests across the workspace (does not compile benches)"
command = "cargo"
args = ["test", "--workspace"]
[tasks.test-lib]
description = "Run unit tests only (--lib): no integration tests, no doctests"
command = "cargo"
args = ["test", "--workspace", "--lib"]
# ============================================================================
# Utility tasks
# ============================================================================
[tasks.clean]
description = "Remove build artifacts (cargo clean). Also deletes a running mutation pass's scratch copies — do not run one while a pass is in flight"
command = "cargo"
args = ["clean"]
[tasks.check]
description = "Type-check the workspace (no codegen; does not compile benches)"
command = "cargo"
args = ["check", "--workspace"]
[tasks.clippy]
description = "Lint the workspace including all targets (benches, examples, tests); denies warnings. Single clippy-gate definition shared by `gate` and the pre-commit hook."
command = "cargo"
args = ["clippy", "--workspace", "--all-targets", "--", "-D", "warnings"]
[tasks.fmt]
description = "Format the workspace with rustfmt"
command = "cargo"
args = ["fmt", "--all"]
[tasks.fmt-check]
description = "Check workspace formatting without modifying files"
command = "cargo"
args = ["fmt", "--all", "--check"]
# ============================================================================
# Documentation tasks
# ============================================================================
[tasks.doc]
description = "Build workspace docs (no deps) and open them in a browser"
command = "cargo"
args = ["doc", "--workspace", "--no-deps", "--open"]
# Gate step: build workspace docs with rustdoc warnings denied, so a
# broken / private intra-doc link or invalid-HTML doc comment fails the
# gate deterministically instead of surfacing in review. rustdoc resolves
# intra-doc links against each item's scope, so a module split or trimmed
# import can invalidate a link with no compiler or clippy diagnostic; the
# `test` step's doctests run rustdoc too, but only as a test compiler —
# they do not lint intra-doc links or HTML, which is what this step adds.
# RUSTDOCFLAGS carries the warnings-as-errors flag because there is no
# equivalent `cargo doc` CLI switch. Default features only, matching the
# rest of the gate, so doc warnings inside the feature-gated arpack / hptt
# regions are out of scope here (nothing doc-builds them under -D warnings).
# No --open, unlike the sibling `doc` task.
[tasks.doc-check]
description = "Build workspace docs denying rustdoc warnings (broken/private intra-doc links, invalid HTML); no browser. Gate step."
env = { RUSTDOCFLAGS = "-D warnings" }
command = "cargo"
args = ["doc", "--workspace", "--no-deps"]
# ============================================================================
# Benchmark tasks
# ============================================================================
[tasks.bench]
description = "Run all Criterion regression benches (tensor + linalg + algorithms)"
dependencies = ["bench-tensor", "bench-linalg", "bench-algorithms"]
[tasks.bench-tensor]
description = "Run the tensor crate's Criterion benches (dense_ops, dense_tensor_scalar_ops)"
command = "cargo"
args = ["bench", "-p", "ariadnetor-tensor"]
# Only the criterion regression benches; the `sweep_*` threshold instruments are
# on-demand (`cargo bench --bench sweep_*`) and excluded here so the regression
# run does not fire their expensive matrix-size sweeps.
[tasks.bench-linalg]
description = "Run the linalg Criterion regression benches (scalar_ops, block_sparse_ops, reorder_sandwich, tridiag_eigh); excludes the on-demand sweep_* instruments"
command = "cargo"
args = [
"bench",
"-p",
"ariadnetor-linalg",
"--bench",
"scalar_ops",
"--bench",
"block_sparse_ops",
"--bench",
"reorder_sandwich",
"--bench",
"tridiag_eigh"
]
# Lanczos arm by default; the ARPACK arm is feature-gated, run ad hoc via
# `cargo bench -p ariadnetor-algorithms --features arpack`.
[tasks.bench-algorithms]
description = "Run the algorithms Criterion regression bench (dmrg_local_eigensolver, Lanczos arm)"
command = "cargo"
args = ["bench", "-p", "ariadnetor-algorithms"]
# ============================================================================
# Release / publish
# ============================================================================
# Thin passthrough to cargo-release (install once: cargo install cargo-release).
# All release policy — shared version, internal-dep version upgrade,
# dependency-ordered publish with index-wait, single workspace tag — lives in
# release.toml; this task only forwards arguments so the canonical invocation is
# discoverable and does not drift. Version is per-release, so it is passed as an
# argument rather than baked into a task.
#
# cargo make release 0.0.4 # dry-run: prints the full plan
# cargo make release 0.0.4 --execute # bump + publish + tag (no push)
#
# Pass the version and flags directly, WITHOUT a `--` separator: cargo-make
# forwards a `--` into the `cargo release` command, where clap then reads a
# following `--execute` as a positional and aborts the release.
#
# release.toml sets push = false: after --execute, push the release commit + tag
# past the default-branch guard with
# SKIP=protect-default-branch git push --follow-tags
[tasks.release]
description = "Release via cargo-release (dry-run unless --execute); policy in release.toml. Usage: cargo make release <version> [--execute]"
command = "cargo"
args = ["release", "${@}"]
# ============================================================================
# Composite tasks
# ============================================================================
[tasks.gate]
description = "Local pre-PR gate: fmt-check + clippy (--all-targets, compiles benches) + test (unit/integration/doctests) + doc-check (rustdoc warnings denied); does not run benchmarks"
dependencies = ["fmt-check", "clippy", "test", "doc-check"]
[tasks.dev]
description = "Fast local loop: fmt + check + test (skips clippy and benches)"
dependencies = ["fmt", "check", "test"]
# ============================================================================
# QA tasks (outside the gate)
# ============================================================================
# Pluggability litmus: rebuild the host-pinned crates with the `Host`
# substrate aliased to a distinct stateful backend and run their tests, so
# the call-site-backend design is proven to hold against a non-native
# substrate. Deliberately NOT a `gate` dependency — the per-diff regression
# vectors are covered by the pre-commit audits, so this heavier rebuild runs
# on demand when the host-pinned surface changes or before a PR. The package
# set and feature flag are the canonical form and must not drift.
[tasks.litmus]
description = "Pluggability litmus: build + test the host-pinned crates with the alternate Host substrate (cargo make litmus)"
command = "cargo"
args = [
"test",
"-p",
"ariadnetor-tensor",
"-p",
"ariadnetor-linalg",
"-p",
"ariadnetor-mps",
"-p",
"ariadnetor-algorithms",
"-p",
"ariadnetor",
"--features",
"pluggability-litmus",
]
# Layer-leak gate: cargo-check-external-types verifies that no lower-layer or
# foreign type leaks through a crate's public API beyond its allow-list. It
# runs over every crate that ships a crates/<crate>/allowed-external-types.toml,
# so adding that file is all it takes to gate a new crate (the on-disk config
# is the single source of the gated set — no list to keep in sync here). Mid-
# layer crates use EXACT lists; the umbrella uses workspace-facade globs plus
# exact non-workspace exceptions. Deliberately NOT a `gate` dependency: it needs
# nightly + a full rustdoc build, too heavy for the per-commit path. See
# CONTRIBUTING.md for the nightly / cargo-check-external-types version pairing.
[tasks.external-types]
description = "Layer-leak gate: cargo-check-external-types per gated crate against its allow-list (cargo make external-types); not a gate dependency, see CONTRIBUTING.md for toolchain requirements"
script_runner = "@shell"
script = '''
set -e
for cfg in crates/*/allowed-external-types.toml; do
dir=$(dirname "${cfg}")
echo "== check-external-types: ${dir} =="
cargo +nightly check-external-types \
--manifest-path "${dir}/Cargo.toml" \
--config "${cfg}"
done
'''
# Print the public API surface per crate, for review of surface changes.
# Advisory only (no committed baseline pre-publish). Bare `cargo public-api`
# fails in a workspace, hence the per-package loop. To diff against a
# published baseline, run `cargo public-api -p <crate> diff vX..vY` manually.
[tasks.public-api]
description = "Print the public API surface per crate for review (cargo make public-api); advisory, outside the gate"
script_runner = "@shell"
script = '''
set -e
for crate in ariadnetor-core ariadnetor-tensor ariadnetor-linalg ariadnetor-native ariadnetor-mps ariadnetor-algorithms ariadnetor; do
echo "== public-api: ${crate} =="
cargo public-api -p "${crate}"
done
'''
# cargo-mutants exits with "create temp dir" if TMPDIR does not exist.
[tasks.mutants-scratch]
private = true
script_runner = "@shell"
script = 'mkdir -p "${MUTANTS_SCRATCH}"'
# The shipped pass, with the scratch redirect a bare `cargo mutants` lacks.
# `${@}` keeps this a drop-in for the bare command: without it cargo-make
# drops whatever follows the task name in silence, so `cargo make mutants
# --list` would launch the full multi-day pass. Pass flags WITHOUT a `--`
# separator, for the reason the release task's comment gives — here a
# forwarded `--` would additionally make cargo-mutants read the rest as
# cargo-test arguments.
[tasks.mutants]
description = "Shipped mutation pass (default features, hptt off, arpack off); extra cargo-mutants flags forward, no -- separator"
env = { TMPDIR = "${MUTANTS_SCRATCH}" }
dependencies = ["mutants-scratch"]
command = "cargo"
args = ["mutants", "${@}"]
# Faithful mutation passes for code the shipped `cargo make mutants` run
# cannot reach. The shipped run (.cargo/mutants.toml, default features) builds
# hptt OFF and arpack OFF, so two regions never see a live mutant: the
# ARPACK backend (never compiled) and the HPTT transpose kernels (not
# compiled under the hptt-off default). These two passes restore them. Each
# writes to its own
# target/mutants-<pass> directory (set per task below); triage each pass's
# output separately — a "missed" there means untested, same as the shipped
# run's default mutants.out.
# ARPACK pass: the krylov ARPACK backend (krylov/arpack.rs, wholly
# #[cfg(feature = "arpack")]) and the ARPACK branch of
# validate_eigensolver_params (dmrg/solver.rs) are OFF by default, so their
# mutants trivially pass the shipped run. `--features arpack` compiles them;
# the two `--file` globs scope mutation to just those files so the pass
# audits the feature-gated region instead of re-mutating the whole crate
# (the rest is already covered by the shipped run). solver.rs is mutated
# whole — its ARPACK match arm shares a function name with the sibling
# Lanczos arm and cannot be name-filtered apart from it — so a few
# non-ARPACK solver mutants overlap the shipped run; their verdicts are
# identical there (algorithms has no cross-crate test consumer), so the
# overlap is redundant, not contradictory. `--test-workspace false` scopes
# testing to the algorithms crate's own unit + integration tests
# (tests/arpack_smallest.rs, tests/dmrg_arpack.rs) — the only tests that can
# kill these mutants; it is an optimization here, not a correctness
# requirement. `--output` keeps this pass's results out of the shipped run's
# default mutants.out. Needs the system ARPACK library at build time.
# Neither scoped pass takes `${@}`, unlike the shipped one: cargo-mutants
# treats a repeated `--file` / `--re` as an addition, so forwarding here
# would turn an attempt to narrow the pass into a silent widening.
[tasks.mutants-arpack]
description = "Mutation pass over the feature-gated ARPACK backend (cargo mutants --features arpack); requires the system ARPACK library"
env = { TMPDIR = "${MUTANTS_SCRATCH}" }
dependencies = ["mutants-scratch"]
command = "cargo"
args = [
"mutants",
"-p",
"ariadnetor-algorithms",
"--features",
"arpack",
"--file",
"crates/ariadnetor-algorithms/src/krylov/arpack.rs",
"--file",
"crates/ariadnetor-algorithms/src/dmrg/solver.rs",
"--test-workspace",
"false",
"--output",
"target/mutants-arpack",
]
# HPTT-kernel pass: to_hptt_order / to_hptt_num_threads / hptt_f64 / hptt_f32
# / hptt_c64 / hptt_c32 in ariadnetor-native/src/transpose.rs are
# #[cfg(feature = "hptt")], not compiled under the default (hptt-off)
# build. `--features hptt` compiles them; `--file` + `--re` scope
# mutation to exactly those gated kernels. The scope is REQUIRED for a
# faithful result, not an optimization — without it the pass also mutates
# - the naive fallback in the same file (cfg'd out under `--features hptt`,
# so its mutants surface as false gaps), and
# - the rest of the native crate (gemm/qr/svd/...), which the shipped run
# already audits; re-mutating it here is redundant, and under the
# package-scoped tests this pass uses (see --test-workspace below) any
# native mutant the shipped run kills only via a cross-crate test
# (test_workspace = true) would additionally surface as a false gap.
# `--test-workspace false` is an OPTIMIZATION here, not a correctness
# requirement (the reverse of the naive pass it replaced): with `--features
# hptt` selected on `-p ariadnetor-native`, feature unification keeps
# native/hptt ON under a workspace test too, so the HPTT path is never
# compiled out. Package-scoped testing (native's only dev-dep is rstest)
# runs tests/transpose.rs against the HPTT path and trims cross-crate MISSED
# noise. `--output` keeps this pass's results out of the shipped run's
# default mutants.out.
[tasks.mutants-hptt]
description = "Mutation pass over the feature-gated HPTT transpose kernels (cargo mutants --features hptt)"
env = { TMPDIR = "${MUTANTS_SCRATCH}" }
dependencies = ["mutants-scratch"]
command = "cargo"
args = [
"mutants",
"-p",
"ariadnetor-native",
"--features",
"hptt",
"--file",
"crates/ariadnetor-native/src/transpose.rs",
"--re",
"hptt_f64|hptt_f32|hptt_c64|hptt_c32|to_hptt_order|to_hptt_num_threads",
"--test-workspace",
"false",
"--output",
"target/mutants-hptt",
]