Skip to content

Commit 15ce353

Browse files
committed
docs/20: why one lane's interface is generated and the other's is written
The seam is written by hand and the shader lane's equivalent is generated, which reads as an inconsistency until the reason is stated. A device translation unit is code, and its interface is a design decision no generator makes well; a shader is data, and its interface is an address and a size. Both are already invisible to a consumer -- only the seam includes the C header, and everything downstream imports the module -- so the code lanes have been module-first all along. The shader lane was the exception until 2026.9.7.1, where the generated header WAS the interface. Added in both languages.
1 parent f7f7358 commit 15ce353

2 files changed

Lines changed: 44 additions & 0 deletions

File tree

docs/20-heterogeneous-builds.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,30 @@ C++ ABI. The island should avoid the standard library, because an island that
146146
links libstdc++ puts a second copy of the C++ runtime into a program whose own
147147
copy came from mcpp's toolchain.
148148

149+
150+
### Two kinds of lane, and only one of them has a generated interface
151+
152+
The seam above is written by hand, and the shader lane's equivalent is
153+
generated. That is not an inconsistency; the two lanes carry different things.
154+
155+
**A device translation unit is code.** Its interface is a design decision --
156+
which functions, which types, what happens on failure -- and no generator can
157+
make that decision well. So CUDA, HIP, SYCL and Ascend C get a hand-written
158+
seam, and the `extern "C"` header exists for the ABI reason above. Both are
159+
already invisible to a consumer: only the seam includes the header, and
160+
everything downstream writes `import app.saxpy`. **These lanes are module-first
161+
today and always have been.**
162+
163+
**A shader or an embedded file is data.** Its interface is an address and a
164+
size, which is mechanical, so a rule package generates it and a consumer writes
165+
`import myapp.shaders` without naming a generated file either. Before mcpp
166+
2026.9.7.1 that lane was the one exception: the generated header *was* the
167+
interface, and every consumer named it.
168+
169+
So the rule is not "generate the interface" or "write it by hand". It is: a
170+
mechanical interface is generated, a designed one is written, and in both cases
171+
the header is an intermediate that no consumer names.
172+
149173
## Compiling an island
150174

151175
The command that invokes a device compiler is not built into mcpp. It is

docs/zh/20-heterogeneous-builds.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,26 @@ tarball 已经发出去了。设备源文件必须被显式点名。
117117
岛本身应当避开标准库,因为一个链接了 libstdc++ 的岛,会把第二份 C++ 运行时放进一个
118118
自身运行时来自 mcpp 工具链的程序里。
119119

120+
121+
### 两类 lane,只有一类的接口是生成的
122+
123+
上面那个接缝是手写的,而 shader 那条 lane 的对应物是生成的。这不是不一致 ——
124+
两条 lane 承载的东西不同。
125+
126+
**设备编译单元是代码。** 它的接口是一个设计决定 —— 有哪些函数、什么类型、失败怎么报
127+
—— 而没有任何生成器能把这个决定做好。所以 CUDA、HIP、SYCL 与 Ascend C 有一个手写的
128+
接缝,而那个 `extern "C"` 头文件因为上面那条 ABI 理由而存在。两者对消费者**都已经是
129+
不可见的**:只有接缝包含那个头文件,下游一律写 `import app.saxpy`**这些 lane 今天
130+
就是模块优先的,而且一直如此。**
131+
132+
**shader 或一份被嵌入的文件是数据。** 它的接口是一个地址加一个尺寸,这是机械的,所以
133+
由规则包生成,消费者同样不写出任何生成物的名字,只写 `import myapp.shaders`。在
134+
mcpp 2026.9.7.1 之前,那条 lane 是唯一的例外:生成的头文件**就是**接口,而每个消费者
135+
都得写出它的名字。
136+
137+
所以规则不是「接口要生成」也不是「接口要手写」。规则是:**机械的接口生成,设计出来的
138+
接口手写,而两种情况下头文件都是没有任何消费者会写出其名字的中间产物。**
139+
120140
## 编译一个岛
121141

122142
调用设备编译器的那条命令不内置在 mcpp 里,而是由**构建规则包**提供 ——

0 commit comments

Comments
 (0)