CHAPTER 45 / Cerebras · 晶圆级计算
WSE 与 PE:把数据放在拥有它的计算节点旁边
三个PE各有两项数据,怎样得到一个全局结果?
这一章要弄清楚
- 区分PE本地存储与全局数学数组
- 解释复制计算与分布计算的差异
- 用容量与通信量约束问题分解
先备知识:并行分解、分块与负载均衡 / Reduction、scan 与数值正确性
C++20 本机逻辑模型;不是设备仿真或性能测量。厂商语法片段未在设备或 SDK 执行,实际 API 以匹配版本的公开文档为准。
先把一个大问题拆成小所有者
假设六个整数为2、4、6、8、10、12,总和是42。我们让三个教学节点各持有两项,局部和分别是6、14、22。这里的“全局数组”是数学视图,实际数据可以分散在不同所有者。某节点要使用另一个节点的结果,必须通过明确的数据移动或通信得到它,不能凭空读取一个全局变量。
Cerebras的WSE由大量PE组成。公开CSL材料把PE程序、本地数据和PE之间的通信放在显著位置。初学时可以先想成许多小工作台,每个工作台附近有自己的材料,工作台之间按安排传递消息。这只是帮助建立所有权和通信直觉;真实路由、任务激活和资源限制需要对应SDK及架构文档。
复制同一程序,不等于把工作分开
公开多PE教程先展示在多个PE复制相同工作,再进一步展示跨PE共同完成一个计算。这两个阶段不能混淆。如果三个PE都处理完整六项输入,每个都得到42,再把它们相加得到126,就重复计算了三次。真正的数据并行分解需要明确每项由谁负责,以及最终结果怎样合并。
例一使用三个独立vector保存三份不重叠数据,然后显式收集局部和。它是普通C++逻辑模型,不是Cerebras fabric simulator。模型没有模拟PE指令、路由、时钟或通信阻塞;它验证的是数据分区和局部结果合并的数学关系。
本地容量迫使程序做预算
如果一个教学PE可给这次问题使用六个元素位置,而输入、输出和通信缓冲分别需要三、二、二,总需求七,已经超预算。不能因为输入只有三个元素就认为一定放得下。中间状态、双缓冲、暂存结果和协议数据也消耗空间。例二对这类预算做显式检查。
真实PE的本地存储还要考虑代码与实现资源,容量及布局受目标代际和SDK约束。教材不把某代产品的固定数字当所有设备共同性质。工作分配策略应该先满足容量与通信合同,再讨论增加并发;平均分配元素数也不一定平均分配计算量。
通信是算法的一部分
局部和6、14、22可以由host回读合并,也可以通过PE之间的某条通信算法合并。这两种方案的结果可能相同,但数据流、同步和性能含义不同。报告时要说清最终合并发生在哪里,不能把host完成的一步写成设备内完成。
沿一条三节点链传递累积值时,第一个发6,第二个加14后发20,第三个加22得42。链式依赖便于理解,却并非一定是性能最优方案。更复杂树形或集合通信需要更完整的路由和同步设计;先做对简单路径,才能清楚评估进一步并行化的收益与代价。
将图变成可验证程序
先在纸上写每个节点的输入、输出、发送内容和结束条件,再写CPU reference。测试至少包括一个节点、空分区、不能整除的长度、零值和负值。消息数量也应成为合同:等待两条消息的接收端,必须确实有两条对应发送。
学习本章时可以直接运行原创C++例子,核对数学与容量推理。真实CSL代码、fabric simulator运行和WSE硬件执行分别是后续不同层次的验证。我们只查公开资料,不需要读取任何私有项目源码或SDK结果,就能建立这个基本模型。
三个本地分区的累积
每个元素仅属于一个教学节点。
先在各分区求和。
显式通信模型产生全局和。
阅读完整推演文字
- 分区
PE0 model:2 4;PE1 model:6 8;PE2 model:10 12
每个元素仅属于一个教学节点。
- 局部
PE0:6;PE1:14;PE2:22
先在各分区求和。
- 合并
P0→P1:6;P1→P2:20;P2 result:42
显式通信模型产生全局和。
跟着例子,走完一遍
三个局部所有者
三个分区[2,4]、[6,8]、[10,12]。
- 各自求局部和6、14、22
- 显式收集局部结果
- 合并并比较全局oracle
// Original CPU teaching model; not a device simulator or benchmark.
#include <iostream>
#include <vector>
#include <numeric>
#include <stdexcept>
void require(bool ok) { if (!ok) throw std::runtime_error("model check failed"); }
int main() {
const std::vector<std::vector<int>> local{{2,4},{6,8},{10,12}};
std::vector<int> partial;
for(const auto& values:local) partial.push_back(std::accumulate(values.begin(),values.end(),0));
const int total=std::accumulate(partial.begin(),partial.end(),0);
require(partial==std::vector<int>({6,14,22}) && total==42);
std::cout<<"partials="<<partial[0]<<' '<<partial[1]<<' '<<partial[2]<<" total="<<total<<'\n';
}
partials=6 14 22,total=42。
分区互不重叠,合并位置是CPU模型。
在本机运行这个例子
下载后,在文件所在目录执行。需要支持 C++20 的编译器;POSIX 示例还需要章节说明中的系统条件。
clang++ -std=c++20 -Wall -Wextra -Wpedantic -Werror -pthread 41-a.cpp -o example && ./example预期标准输出:
partials=6 14 22 total=42
不能只算输入的容量预算
教学可用容量6项;输入3、输出2、通信2。
- 分别列三类存储
- 计算需求7
- 拒绝超预算配置
// Original CPU teaching model; not a device simulator or benchmark.
#include <iostream>
#include <stdexcept>
void require(bool ok) { if (!ok) throw std::runtime_error("model check failed"); }
int main() {
const int input=3,output=2,communication=2,capacity=6;
const int required=input+output+communication; const bool fits=required<=capacity;
require(required==7 && !fits);
std::cout<<"required="<<required<<" capacity="<<capacity<<" fits="<<fits<<'\n';
}
required=7 capacity=6 fits=0。
容量是假设元素位置,不是任何真实PE参数。
在本机运行这个例子
下载后,在文件所在目录执行。需要支持 C++20 的编译器;POSIX 示例还需要章节说明中的系统条件。
clang++ -std=c++20 -Wall -Wextra -Wpedantic -Werror -pthread 41-b.cpp -o example && ./example预期标准输出:
required=7 capacity=6 fits=0
把复制误当分区
每个节点都计算全输入,再把结果全部相加。
修正思路:明确每项所有者与合并语义,区分replication和partitioning。
轮到你动手
先写预测或代码,再按需打开提示。完整答案用于对照自己的推理。
练习 1
把五项1分给三个PE,列一种合法分区及局部和。
给我一点提示
- 每项恰属一个PE
- 最后分区可以更小
查看答案与推理
可分[1,1]、[1,1]、[1],局部和2、2、1,总和5。需记录各分区真实长度,不能让尾部多读取一项。
练习 2
三节点链局部和6、14、22,列两次发送及最终值。
给我一点提示
- 消息承载累计值
- 不要把局部值重复加两次
查看答案与推理
PE0发6;PE1收到6后加14,向PE2发20;PE2收到20后加22得到42。host若读取最终节点,只读一次结果;若同时回读所有累计值再相加,会重复计数。
把理解说出来
先用中文讲清因果,再用英文回答。问题依据技能主题编写,并非公司内部题库。
全局数组是否意味着任意PE都能直接访问所有元素?
参考回答 / English answer
不意味着。数学视图与实际分布不同,远端数据需要明确通信或搬运。
A global mathematical array does not imply direct access from every PE. Distributed ownership requires explicit data movement.三个PE各算完整总和42,再合并会怎样?
参考回答 / English answer
得到126,重复计数;需分区或明确只取一份复制结果。
Combining all three replicated results produces one hundred twenty-six. Work partitioning and replication have different contracts.本地容量只统计输入够吗?
参考回答 / English answer
不够,还应考虑输出、中间、通信、双缓冲及代码等实现资源。
Inputs are only part of the memory budget. Outputs, temporaries, communication buffers, and implementation resources also matter.host合并局部结果能叫设备内reduction吗?
参考回答 / English answer
不能,需明确合并位置;它仍可作为正确性baseline。
Host aggregation can be a useful baseline. It is not a device-internal reduction.空分区为什么是重要测试?
参考回答 / English answer
可能没有数据却仍需要参与协议或贡献单位元,错误等待容易暴露。
An empty partition still needs a defined protocol behavior. It can expose missing identity handling or impossible waits.CPU三节点模型与fabric simulator区别?
参考回答 / English answer
前者只运行自定义C++逻辑;后者执行特定SDK设备程序模型,均不直接等于硬件实测。
Our CPU model evaluates a mathematical decomposition. A fabric simulator executes an SDK-specific device model, which is still distinct from hardware.继续查证
- Cerebras public multiple-PE tutorial ↗
Replication and layout coordinates
- Cerebras public routing tutorial ↗
Partitioned computation and communication
公开资料用于查证;本章图解和例题是独立教学内容。CPU 逻辑模型不能证明设备性能。