TrioSim 模拟器 (二):Trace 的产生和处理
生成 Trace 并转换为 TrioSim 格式
Trace 的采集与格式转换主要由以下两个脚本完成:
tracer/datacollect.pytracer/dataprocess.py
具体使用方法可参考:TrioSim 模拟器(一):事件驱动模拟。
由于本文重点介绍模拟器本身的运行机制,因此暂不展开脚本的具体实现细节,后续将另行补充说明。
TrioSim 模拟器加载 TrioSim 格式 Trace
TrioSim 模拟器启动时,会在 triosim/main.cpp 中通过如下代码加载 Trace 数据:
int main()
{
// ...
// 加载 TrioSim 格式的 Trace
triosim::Trace trace = LoadTrace(config.batch_size, config.batch_size_sim);
// ...
}
Trace 加载过程主要包括以下三部分:
- 对数据规模和执行时间进行缩放;
- 解析
tensor.csv; - 解析
trace.csv。
数据规模与执行时间缩放
模拟器会根据运行时参数 --batch-size 和 --batch-size-sim 计算缩放比例。
其中,--batch-size 必须与使用 tracer/datacollect.py 采集 Trace 时的 batch size 保持一致;--batch-size-sim 则表示模拟时希望使用的 batch size。
缩放比例计算公式为:
该比值可以大于 1,也可以小于 1。代码中在函数:
triosim::Trace LoadTrace(int batchSizeTrace, int batchSizeSim)
内通过如下语句实现:
double bsRatio = static_cast<double>(batchSizeTrace) / static_cast<double>(batchSizeSim);
程序假设所有数据大小和算子执行时间都与 batch size 成正比,因此会通过除以 bsRatio 的方式,对数据规模和执行时间进行相应缩放。
解析 tensor.csv
tensor.csv 由 trace.cpp 中的以下函数负责解析:
std::map<std::string, Tensor> TraceLoader::ReadTensors()
解析得到的张量信息会存储到 trace.hpp 中定义的 Tensor 类中。
tensor.csv 的表头如下:
Index,TensorID,TensorShape,TensorNumElement,TensorEachByte,TensorType,TensorStorgeid,gpuid
以 sample_trace/trace2-h100-bs128/vgg13/tensor.csv 为例,前几行内容如下:
0,4,"[128, 3, 224, 224]",19267584,4,input,5,0
1,6,"[64, 3, 3, 3]",1728,4,weight,7,0
2,8,[64],64,4,bias=None,9,0
3,14,"[128, 64, 224, 224]",411041792,4,output,15,0
4,14,"[128, 64, 224, 224]",411041792,4,input,15,0
各字段含义如下:
Index:张量唯一索引,按顺序递增。TensorID:张量 ID,用于在 tensor map 中索引该张量的信息。TensorShape:张量形状。TensorNumElement:张量元素个数。TensorEachByte:每个张量元素占用的字节数。TensorType:张量类型。TensorStorgeid:暂未使用。gpuid:暂未使用。
解析 trace.csv
trace.csv 由 trace.cpp 中的以下函数负责解析:
Trace TraceLoader::ReadLayers(std::map<std::string, Tensor>& tensors)
解析得到的算子信息会存储到 trace.hpp 中定义的 Layer 类中。
trace.csv 的表头如下:
OperatorID,OperatorName,Operator_input,Operator_output,Operator_cudatime,Operator_cudatimenooverlap,InputSize,OutputSize,gpuid,stage,tpflag
以 sample_trace/trace2-h100-bs128/vgg13/trace.csv 为例,前几行内容如下:
1,aten::conv2d,[4; 6; 8],[14],2673,2671,[19267584; 1728; 64],[411041792],0,forward,1
2,aten::relu_,[14],[14],1083,1083,[411041792],[411041792],0,forward,0
3,aten::conv2d,[14; 22; 24],[30],5901,5892,[411041792; 36864; 64],[411041792],0,forward,1
4,aten::relu_,[30],[30],1081,1081,[411041792],[411041792],0,forward,0
各字段含义如下:
OperatorID:层唯一索引,按顺序递增。OperatorName:当前层的算子名称。Operator_input:输入张量列表。其值对应tensor.csv中的TensorID,用于在 tensor map 中索引对应张量的信息。Operator_output:输出张量列表。其值对应tensor.csv中的TensorID,用于在 tensor map 中索引对应张量的信息。Operator_cudatime:当前未使用。Operator_cudatimenooverlap:当前层的实际执行时间,单位为微秒,即 us。InputSize:输入张量的元素总数。OutputSize:输出张量的元素总数。gpuid:暂未使用。stage:当前层所属的传播阶段,例如"forward"或"backward"。tpflag:当前层是否可以参与张量并行。1表示可以,0表示不可以。
所有解析得到的 layer 会共同组成一条 Trace。代码中定义为:
using Trace = std::vector<Layer*>;
模拟器后续的执行过程都会基于该 Trace 进行处理。
评论