docs(arch): ARCH-01..15 — review issues on the architecture baseline - #140
Conversation
…icy, serving metrics
|
Added four observability issues (ARCH-16..19), so the file now carries 19. Measured across the 13 baseline documents: 10 × "metric", 6 × "diagnostic", 1 × "observab", and 0 × telemetry, tracing, logging, counters. On
|
ARCH responses — positions on the baseline reviewResponses to One position per issue: Accept, Accept with modification, Reject, Postpone. Positions are Every position is grounded in a TornadoVM capability that exists, or names the capability that does not Note on scope: the PR body and title say 15 issues (ARCH-01..15); the file contains 19 — its own Summary
Tally: 12 Accept, 6 Accept with modification, 1 Accept-narrowed, 0 Reject. The modifications carry Two severity changes: ARCH-08 and ARCH-09 up to High (both are preconditions for ARCH-01/02, so they are TornadoVM capability ledgerThe review's asks divide cleanly into three groups. This is the grounding for every position below. Already available — GPULlama simply does not use it
The single most useful fact in this ledger: every metric ARCH-16, 17 and 19 ask for is already produced Needs no TornadoVM capability at all — pure host-side Java
Missing — would have to be proposed upstream
|
ARCH-01 — KV cache ownership prevents paged and shared-prefix KVPosition: Accept. Critical, and settle before phase 1 lands the ArchUnit module. He is right and my Rule 7 is wrong as written. I wrote it against a real problem — cache on the model, Grounding. Lease semantics need nothing from TornadoVM: PR #129's paged mode already allocates one What changes.
|
ARCH-02 — No engine layer: continuous batching has no homePosition: Accept. Critical. My layering has no tier owning scheduling across sequences, so it can only express "one request, one Grounding. The engine tier is pure host-side Java — admission, batch composition, block accounting. What changes.
|
ARCH-03 — Rule 8 forbids the on-device sampler that already existsPosition: Accept. Settle before phase 1. Verified on Grounding. On-device sampling is an ordinary TornadoVM task in the logits graph — a kernel writing What changes.
|
ARCH-04 — No phase promotes the batched-decode enginePosition: Accept. High. My "what is deliberately not scheduled" section excluded "new performance work… must not block them", Grounding. #129 runs today on TornadoVM 5.x using What changes. New phase 3b — promote the batched-decode engine, after the session/state split |
ARCH-05 — Quantization/dtype seam excluded from scopePosition: Accept with modification. High. Accept the distinction: new formats are correctly out of scope, the dtype seam is in scope and Reject the sub-claim that the collapse can be "M operation templates × D schemes" all the way down. Grounding for the flagship goal. MXFP4/NVFP4 has no TornadoVM support: What changes. Phase 5 objective gains "operations are |
ARCH-06 — Phase 1 has no numerical regression netPosition: Accept with modification. High. This is the issue I most regret omitting: I wrote Reject the sub-claim that goldens can be "bit-identical" as a blanket property. Bit-exactness holds Modified proposal.
|
ARCH-07 —
|
ARCH-08 — Prefix cache has no ownerPosition: Accept. Raising severity Medium → High, because it is a precondition for ARCH-01's Grounding. Already implemented and measured in #129: What changes. |
ARCH-09 — Backend SPI has no device-memory allocation seamPosition: Accept. Raising severity Medium → High: an admission scheduler cannot exist without Grounding — this is better supported than the issue claims. TornadoVM already exposes everything Note for the design: TornadoVM has no user-facing sub-buffer allocator, so a block pool is one large What changes. Backend SPI gains buffer lifetime classes — model lifetime (weights), engine lifetime |
ARCH-10 — Backend SPI does not express native library dispatchPosition: Accept, narrowed. Severity Medium → Low. Accept the one-sentence addition to ADR-003: an operation implementation may be backed either by a Grounding. The mechanism exists in TornadoVM — Why narrowed. #131's own conclusion is parity, not a win: the JIT matvec at 553.8 µs/call and ~948 |
ARCH-11 — Rule 13 has no benchmark gatePosition: Accept with modification. Medium. Accept binding Rule 13 to existing machinery rather than inventing any: Reject the sub-claim that "within 3% of the previous recorded run on the same machine and model" is Modified proposal.
|
ARCH-12 — Model provider SPI lands at phase 8, after the painPosition: Accept with modification. Medium. Accept the problem: model support is the most frequent change here, #120 (Gemma 4) is in flight, and Modification: split phase 8 rather than move it wholesale, because his premise ("depends mainly on
What changes. Phase 8 splits; 8a moves ahead of phases 5–7 in the dependency summary. Add the |
ARCH-13 — In-flight PRs are not sequenced against the phasesPosition: Accept. Medium. My roadmap referenced no open PR, which is a real omission for a plan Verified open: #120 (Gemma 4, CPU + GPU, BF16 and Q8_0), #129 (static batched decode), #131 (hybrid CUDA Proposed land order, with reasons rather than preferences.
Freeze declaration: |
ARCH-14 — Multi-device execution absent from the target architecturePosition: Accept — seams only, no implementation. Severity Low → Medium. I am upgrading this because the framing "record the seam now, it is cheap" undersells what I found: So this is not a hypothetical future capability constraining a design — it is an available capability my What changes. |
ARCH-15 — Public API does not expose quantization of a loaded modelPosition: Accept. Low, uncontroversial, and he is right that it is the first thing every consumer What changes. |
ARCH-16 — No metrics seam, device metrics cannot reach their consumerPosition: Accept. High. The best issue in the set, and the one that found a real hole in my His structural point is correct and I missed it: metrics have the opposite dependency direction to Grounding — and the evidence that this is the default failure. TornadoVM already produces all of it: What changes. A metrics sink interface in the runtime layer, below the backend SPI's consumers: One caveat to design in: |
ARCH-17 — Observability scheduled last, but earlier phases need it nowPosition: Accept. Medium. Consistent with accepting ARCH-06 and ARCH-11: every phase claiming "no What changes. Split my phase 10. Early (alongside the phase 1 guardrails): the ARCH-16 seam plus load, |
ARCH-18 — No logging policy for an embeddable libraryPosition: Accept with modification. Medium. Verified: 65 Modification: no external logging facade dependency. He suggests "a facade (or a no-op-by-default What changes. Logging policy stated in |
ARCH-19 — Serving-level metrics are undefinedPosition: Accept. Medium. Follows from accepting ARCH-02 and ARCH-16: once an engine tier exists, Grounding. #129 already reports slot utilization (82.2%), steps, gen tok/s and req/s per scheduling What changes. Engine tier defines: time to first token, queue wait, batch occupancy / slot |
Consequences for the baseline if all positions are agreedDocument edits:
Sequencing note: ARCH-01, 03 and 16 change rules that phase 1 would otherwise encode, so they should be |
Response to the positions — agreed on all 19, with two corrections to the ledgerTaking the positions as written: 12 Accept, 6 Accept-with-modification, 1 narrowed, 0 Reject. I accept
The ARCH-16 framing is also better than mine: an explicitly designed dependency permission Correction 1 — ARCH-07: the capability exists, so the reason to batch is different
This is not right, and it matters because the document would otherwise record a non-existent upstream The conclusion — batch inside one compiled program — is still right, but for a reason that is stronger
So ARCH-07 resolves as: batching inside one plan, because per-plan buffer duplication makes parallel Correction 2 — the ledger is not reachable from the pinned versionYou flagged that
So "Int8 and FP8 MMA are available now, a Q8_0 tensor-core matmul needs no upstream work" (ARCH-05) is One more ledger row, because it was a no-op until today: |
Addendum — five runtime constraints the engine tier has to be designed aroundThe ledger answers "does the capability exist". These are cases where the capability exists and 1. CUDA-graph capture and a block pool are compatible in exactly one shape — ADR-005
So a 2. Any tok/s history recorded before last week is not a baseline — ARCH-11
3. Compiled-program identity was not well-defined until #999 — ADR-002, ARCH-11Generated kernel source was non-deterministic across JVM runs: 4. The engine tier will generate far more bytecode per step than single-stream — ARCH-06The interpreter's bytecode buffer was a fixed 4096 bytes; a ~50-task graph overflowed it and the Concrete ask for the ARCH-06 net: run the golden suite with 5. Observability: the data is there, and the log now aggregates it — ARCH-16/19Beyond
Amendments to the consequences tableOtherwise I agree with it as written, including the sequencing note.
Happy to take ARCH-01/02/04/08/09 as the single engine-tier decision in one sitting, as you propose — and |
|
Re: positions summary — Accepting all 19 as written: 12 Accept, 6 with modification, 1 narrowed, both severity upgrades. |
|
Re: ARCH-01 — Agreed, and the lease/manager split is the right correction of my own framing. |
|
Re: ARCH-02 — Agreed, including that this needs no second compiler and does not touch ADR-003. |
|
Re: ARCH-03 — Agreed on 8a/8b, and on keeping Rule 14 as-is. |
|
Re: ARCH-04 — Agreed on a phase 3b that promotes #129 rather than re-implementing it. |
|
Re: ARCH-05 — Conceding the sub-claim: kernels are compiled per concrete native array type and Java has no generics over primitives, so dispatch classes collapse and the per-dtype kernel set does not. Invariant test should read "k dispatch classes + one kernel set per dtype". |
|
Re: ARCH-06 — Conceding the sub-claim; bit-exactness only holds inside a pinned (device, driver, TornadoVM version, backend, build) tuple, and your three tiers are better than what I asked for. |
|
Re: ARCH-07 — Correcting the mechanism claim: concurrent independent plans on one device are exposed and tested. |
|
Re: ARCH-08 — Agreed on the upgrade to High and on prefix identity covering model, dtype and position offset. |
|
Re: ARCH-09 — Agreed, including that the gap is our SPI concept rather than a runtime capability, and that the seam describes pools and lifetimes rather than per-block device allocations. |
|
Re: ARCH-10 — Accepting the narrowing to Low; #131's 0.6% on the n=1 projection path is a tie, and I over-weighted it. |
|
Re: ARCH-11 — Conceding the 3% gate; no machine identity in the schema, so it would have been noise. |
|
Re: ARCH-12 — Agreed; splitting into 8a (source detection and loading, after phase 4) and 8b (program/plan provider, after phase 6) is more accurate than my "move phase 8 earlier". |
|
Re: ARCH-13 — Agreed on the land order and the freeze declaration; #129 first and #138's layout before phase 3's ownership are both better reasoned than "sequence them somehow". |
|
Re: ARCH-14 — Agreed on Medium and on design-only. |
|
Re: ARCH-15 — Agreed, and exposing both weight and compute dtype is a real improvement on my version. |
|
Re: ARCH-16 — Agreed, and your framing improves on mine: an explicitly designed |
|
Re: ARCH-17 — Agreed on splitting phase 10: seam plus load/prefill/decode/tok-s counters early, exporters and memory planning late. |
|
Re: ARCH-18 — Agreed, and take the option you chose: a project-owned no-op sink, no SLF4J, optional bridge in an integration module. |
|
Re: ARCH-19 — Agreed; formalising quantities #129 already measures ad hoc is the cheap version of this. |
|
Re: consequences — Agree with the table as written, and with settling 01/03/16 before ArchUnit and taking 02/04/08/09 as one engine-tier decision. |
Applies the outcome of the architecture review on PR #140, where both maintainers recorded a position on all 19 ARCH issues. All 19 accepted, six with modifications; none rejected. Baseline v1.0. Rules: - Rule 7 reworded: KV storage is owned by an engine-scoped cache manager and leased to sessions. The previous wording made a shared block pool a violation and shared prefix blocks unrepresentable. - Rule 8 split into 8a (generation policy stays out of the backend) and 8b (sampling is an operation and may execute on device). The old form made the shipped on-device sampler a violation. - Rule 16 added: no console I/O outside the CLI integration, with today's 20 files as a shrink-only allowlist. - Rule 17 added: metrics sink in the runtime layer, a designed backend -> runtime.metrics permission rather than an allowlist entry. - Rule 18 added: engine tier direction. New documents: - tornadovm-capabilities.md — capability ledger with minimum-version column and six runtime constraints (C1-C6) that bind the design. - ADR-005 — KV cache ownership, block pools and leases, including the CUDA-graph invariant: one persistent pooled array with in-kernel indexing is the only shape that keeps graph capture. - ADR-006 — the engine tier: scheduling, admission, batching. ADR-001..004 accepted and amended; ADR-001's concurrency question resolved to batching. Roadmap rewritten as an implementation plan: Phase 0 (TornadoVM version floor >= 5.2.x) then M1..M13, each with tasks, acceptance criteria and dependencies. PR land order and a freeze declaration are recorded. Two claims were corrected by evidence during review and the corrected reasoning is now load-bearing: - concurrent independent execution plans on one device are supported and tested; batching is chosen because device buffers are per task graph, so per-session plans duplicate the weights; - the pinned TornadoVM 5.0.0 predates FP8Array (5.1.0), BFloat16Array (5.2.0) and several runtime fixes, hence Phase 0. Documentation only. No production code, tests, Maven config, CI or existing APIs were changed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review of the architecture baseline (
7ee6f86) as 15 ARCH issues, one topic each, indocs/architecture/review/ARCH-issues-mikepapadim.md. Branched off the baseline commit, so the diff isthe review file only.
Nothing here is a change to the architecture documents. Each issue is
Status: Openuntil we go throughthem together and mark it Accept / Reject / Postpone; only accepted ones should be folded into
docs/architecture/.Framing
The baseline is strong on the library axis, and better specified than what I had written separately:
the 15 dependency rules with ArchUnit forms and a shrink-only allowlist, ADR-001 (four lifetimes),
ADR-002 (program vs compiled program), the terminology doc, and the P1–P10 pressure points — P5, P6, P7,
P9 and P10 match what I found independently, and P9's count of 26 files importing
uk.ac.manchester.tornado.*outsidetornadovm/**is the concrete allowlist seed.Most of my issues are on the product axis: the serving path (continuous batching, paged KV, prefix
cache), quantization, and the numbers that decide whether a phase regressed anything. Measured across
all 13 documents: 0 occurrences of continuous batching, PagedAttention, prefix cache, KV cache manager,
scheduler, server/OpenAI; 0 of Q4/Q8_0/FP4/MXFP4; 0 of tensor core/MMA; 1 of CUDA graph.
Two issues are conflicts between a stated rule and code that already exists, so they are worth settling
before phase 1 lands the ArchUnit module — otherwise both become permanent allowlist entries, which
weakens every other rule:
GenerationSessionjavadoc ("Owns KV cache") put cache ownership in thesession, which makes a shared block pool a violation and shared prefix blocks impossible. Suggested
fix keeps the intent (never on the model) and moves ownership up: an engine-scoped manager owns
blocks, sessions hold leases.
..backend..→..generation.., but device-sidesampling is already on
main(LogitsFP16Layer,InferenceEngine,LlamaApp.guardDeviceSample).Suggested fix separates generation policy (stays out of the backend) from sampling as an
operation (may run on the device).
The 15
mainGenerationSessioncannot express concurrent servingEach issue follows the ARCH template: Observation quotes the current wording, Suggestion says what
should change, Rationale says why, Impact names the files and PRs affected.
Base is
refactor/framework-abstractionsso the review sits next to the documents it reviews. Happy tosplit any issue further if it turns out to be carrying more than one decision.