E6013
E6013 — A declaredtransferedge carries an explicit cost *and* has one derivable from its endpoints'bandwidth:figures. An edge gets exactly one cost source, because two answers to "what does this hop cost" is not a model: the compiler routed by the declared number and reported the derived one, and nothing detected the disagreement.
What the compiler reports
E6013 … transfer Memory::GPU_HBM -> Memory::SMEM declares a cost … already derivable
The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.
A program that triggers it
//
// Part of the Vx Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// An edge that states a cost the spaces it connects already imply. E6013.
//
// A transfer edge gets exactly one cost source. `transfer A -> B : 5` states one
// outright; `bandwidth:` on the spaces derives one from bytes and rate. Writing
// both leaves two answers to "what does this hop cost", and a model that answers
// a question twice is not a model -- whichever the compiler picked would be a
// silent decision about which of the programmer's two figures to believe.
//
// So the fix is a choice, and the diagnostic says so: drop the `: …` to use the
// derived figure, or drop the `bandwidth:` if the written one is the one meant.
//
// GPU_HBM -> SMEM is the derivable pair here: both carry a `bandwidth:` and SMEM
// is `within:` GPU_HBM, which is what makes a figure computable from the
// containment tree. The CPU_DRAM -> GPU_HBM edge above it states a cost and is
// fine, because CPU_DRAM declares no bandwidth and nothing is derivable for it.
// That contrast is the point: the rule is about two sources, not about writing a
// cost.
//
Memory CPU_DRAM {}
Memory GPU_HBM {
within: Memory::CPU_DRAM, capacity: 40 GiB, bandwidth: 3 TB/s, managed: cached
}
Memory SMEM {
// Denominated in seconds like GPU_HBM above. A path that mixes cycles and
// seconds is not derivable at all, which would make this file pass for the
// wrong reason.
within: Memory::GPU_HBM, capacity: 228 KiB, bandwidth: 19 TB/s,
granule: 1 KiB, managed: explicit, scope: sm
}
Topology Dev {
arch: nvptx64,
memory: Memory::GPU_HBM,
visible: [Memory::GPU_HBM, Memory::SMEM],
// Fine: CPU_DRAM declares no bandwidth, so nothing is derivable here.
transfer Memory::CPU_DRAM -> Memory::GPU_HBM : 63 GB/s,
// Refused: both ends carry a bandwidth, so this figure is the second answer.
transfer Memory::GPU_HBM -> Memory::SMEM : 5
}
fn main() -> i32 {
return 0;
}
From tests/frontend/fail/transfer_edge_has_one_cost.vx, which asserts this diagnostic on every commit.
Related
Topologies and memoryThe chapter covering the rule this code enforces.
All diagnosticsEvery code the compiler can emit, grouped by stage.
E6012The same
Memory or Topology name is declared by two compilation inputs (e.g. a --machine file and the program). Declarations are name-keyed, so one would silently shadow the other and the machine model in force would depend on load order (#281).
E6014A program stages through host memory while a machine model is in force, and no host was declared. --machine describes an accelerator and says nothing about the machine it hangs off, so the host end of that seam was being reasoned about without anything describing it. --host <file> names one; --host default names the machine compiling the program. A host declares no capacity — host memory is virtual, and a hard limit would reject programs that page rather than fail — so this is about the host being *stated* rather than assumed, not about a budget.