关键特性说明【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit如图1所示本章节将配合时序图介绍CrossCoreSetFlag和CrossCoreWaitFlag配合使用时支持的四种同步控制模式各自实现的原理。模式0AI Core核间的同步控制。对于AIC全核场景同步所有的AIC核直到所有的AIC核都执行到CrossCoreSetFlag时CrossCoreWaitFlag后续的指令才会执行对于AIV全核场景同步所有的AIV核直到所有的AIV核都执行到CrossCoreSetFlag时CrossCoreWaitFlag后续的指令才会执行。模式1AI Core内部AIV核之间的同步控制。如果两个AIV核都运行了CrossCoreSetFlagCrossCoreWaitFlag后续的指令才会执行。模式2AI Core内部AIC与AIV之间的同步控制。在AIC核执行CrossCoreSetFlag之后两个AIV上CrossCoreWaitFlag后续的指令才会继续执行两个AIV都执行CrossCoreSetFlag后AIC上CrossCoreWaitFlag后续的指令才能执行。模式4AI Core内部AIC与单个AIV之间的同步控制。AIV0与AIV1可单独触发AIC等待。图1同步控制模式示意图下述同步特性均以该场景配置为例每个AI Core包含1个AIC和M个AIV共启动N个AI Core即存在N个AIC和M * N个AIV。多AI Core中AIC或者AIV全核同步多AI Core中AIC或者AIV全核同步需要配套使用模式0的CrossCoreSetFlag.md)和CrossCoreWaitFlag.md)接口。该场景可细分为两类N个AI Core中的N个AIC进行全核同步。当N个AIC都执行完CrossCoreSetFlag时每个AIC对应flagId的计数器增加1。若AIC该flagId的计数器为非0被CrossCoreWaitFlag所阻塞的所有指令才会执行下去该flagId的计数器减去1。对于每个AICCrossCoreSetFlag和CrossCoreWaitFlag都必须配对使用。N个AI Core中的M * N个AIV进行全核同步。当M * N个AIV都执行完CrossCoreSetFlag时每个AIV核对应flagId的计数器增加1。若AIV该flagId的计数器为非0被CrossCoreWaitFlag所阻塞的所有指令才会执行下去该flagId的计数器减去1。对于每个AIVCrossCoreSetFlag和CrossCoreWaitFlag都必须配对使用。// 每个核都应该有类似如下的成对调用CrossCoreSetFlag和CrossCoreWaitFlag // modeId必须配置为0, pipe要一致flagId要一致 AscendC::CrossCoreSetFlag0, PIPE_M(0); // 待前置PIPE_M流水任务完成后通知调度模块 AscendC::CrossCoreWaitFlag(0); // 直到所有AIC都完成前置PIPE_M流水调度模块更新flagId0的计数器后解除阻塞。以图1为例演示N2时2个AI Core中的2个AIC进行全核同步。AIC 1中在执行CrossCoreWaitFlag后此时AIC 1 flagId0的计数器为0后续所有指令全部被阻塞需要等到2个AIC核均执行完CrossCoreSetFlag。AIC 2的CrossCoreSetFlag执行完后此时调度模块感知到2个AIC均已执行完CrossCoreSetFlag因此所有AIC各自的flagId0的计数器值增加为1。AIC 1和AIC 2检测到各自对应的flagId0的计数器变为1都解除阻塞继续执行后续指令并且将计数器值减去1。图1模式0多AI Core中AIC全核同步单AI Core中AIV全核同步该场景需要配套使用模式1的CrossCoreSetFlag.md)和CrossCoreWaitFlag.md)接口。1个AI Core中的M个AIV进行全核同步。当M个AIV全部都执行完CrossCoreSetFlag时每个AIV对应flagId的计数器增加1。若AIV该flagId的计数器为非0被CrossCoreWaitFlag所阻塞的所有指令才会执行下去该flagId的计数器减去1。对于每个AIVCrossCoreSetFlag和CrossCoreWaitFlag都必须配对使用。[!CAUTION]注意 该模式中不同AI Core的AIV核之间不会互相影响同步。// 每个AIV都应该有类似如下的成对调用CrossCoreSetFlag和CrossCoreWaitFlag // modeId必须配置为1, pipe要一致flagId要一致 AscendC::CrossCoreSetFlag1, PIPE_MTE3(0); // 待前置PIPE_MTE3流水任务完成后通知调度模块 AscendC::CrossCoreWaitFlag(0); // 直到该AI Core中的所有AIV都完成前置PIPE_MTE3流水调度模块更新flagId0的计数器后解除阻塞。以图2为例演示M2时1个AI Core中的2个AIV进行全核同步。AIV 1-1中在执行CrossCoreWaitFlag后此时AIV 1-1 flagId0的计数器为0后续所有指令全部被阻塞需要等到2个AIV均执行完CrossCoreSetFlag。AIV 1-2的CrossCoreSetFlag执行完后此时调度模块感知到2个AIV均已执行完CrossCoreSetFlag因此将AIV 1-1和AIV 1-2各自的flagId0的计数器值增加为1。AIV 1-1和AIV 1-2检测到各自对应的flagId0的计数器变为1都解除阻塞继续执行后续指令并且将计数器值减去1。图2模式1单AI Core中AIV全核同步单AI Core中AIC与AIV全核同步单AI Core中AIC与AIV全核同步需要配套使用模式2的CrossCoreSetFlag.md)和CrossCoreWaitFlag.md)接口。该场景可细分为两类1个AI Core中的AIC执行CrossCoreSetFlag对应的M个AIV都执行CrossCoreWaitFlag。当AIC执行完CrossCoreSetFlag时M个AIV对应flagId的计数器增加1。若AIV该flagId的计数器为非0则解除AIV的阻塞CrossCoreWaitFlag后的指令继续发射该flagId的计数器减去1。总计AIC 1次调用CrossCoreSetFlag对应M个AIV各1次CrossCoreWaitFlag才算配对使用。1个AI Core中的M个AIV都执行CrossCoreSetFlag对应的AIC执行CrossCoreWaitFlag。当M个AIV全都执行完CrossCoreSetFlag时AIC对应flagId的计数器增加1。若AIC该flagId的计数器为非0则解除AIC的阻塞CrossCoreWaitFlag后的指令继续发射该flagId的计数器减去1。总计M个AIV各1次CrossCoreSetFlag对应AIC 1次调用CrossCoreWaitFlag才算配对使用。// AIC和AIV都应该有类似如下的成对调用CrossCoreSetFlag和CrossCoreWaitFlag // modeId必须配置为2, pipe要一致flagId要一致 if ASCEND_IS_AIV { AscendC::CrossCoreSetFlag2, PIPE_MTE3(0); // 待前置PIPE_MTE3流水任务完成后通知调度模块。必须要所有AIV都执行。 } if ASCEND_IS_AIC { AscendC::CrossCoreWaitFlag(0); // 直到该AI Core中的所有AIV都完成前置PIPE_MTE3流水调度模块更新flagId0的计数器后AIC解除阻塞。 }以图3为例演示M2时1个AI Core中AIV与AIC进行同步AIV发起CrossCoreSetFlag。AIC 1中在执行CrossCoreWaitFlag后此时AIC 1 flagId0的计数器为0后续所有指令全部被阻塞需要等到2个AIV均执行完CrossCoreSetFlag。当AIV 1-2的CrossCoreSetFlag在Vector指令1执行完后前置PIPE_V的指令全部完成CrossCoreSetFlag执行完成但是此时AIV 1-1未执行CrossCoreSetFlag。因此AIC 1 flagId0的计数器还是为0AIC的所有指令依然被阻塞。当AIV 1-1的Vector指令1、2全部执行完毕后前置PIPE_V的指令全部完成CrossCoreSetFlag生效。此时调度模块感知到2个AIV均已执行完CrossCoreSetFlag因此将AIC 1 flagId0的计数器值增加为1。AIC 1检测到对应的flagId0的计数器变为1则AIC 1核解除阻塞继续执行后续指令Matrix指令2并且将计数器值减去1。图3模式2单AI Core中AIC与AIV全核同步AIV进行CrossCoreSetFlag单AI Core中AIC与单个AIV同步单AI Core中AIC与单个AIV同步需要配套使用模式4的CrossCoreSetFlag.md)和CrossCoreWaitFlag.md)接口。该场景可细分为两类1个AI Core中的AIC执行CrossCoreSetFlag对应的AIV执行CrossCoreWaitFlag。当AIC执行完CrossCoreSetFlag时AIV对应flagId的计数器增加1。若AIV该flagId的计数器为非0则解除AIV的阻塞CrossCoreWaitFlag后的指令继续发射该flagId的计数器减去1。总计AIC 1次调用CrossCoreSetFlag单个AIV完成一次CrossCoreWaitFlag才算配对使用。1个AI Core中的1个AIV执行CrossCoreSetFlag对应的AIC执行CrossCoreWaitFlag。当AIV执行完CrossCoreSetFlag时AIC对应flagId的计数器增加1。若AIC该flagId的计数器为非0则解除AIC的阻塞CrossCoreWaitFlag后的指令继续发射该flagId的计数器减去1。总计单个AIV 1次CrossCoreSetFlag对应AIC 1次调用CrossCoreWaitFlag才算配对使用。// AIC和AIV都应该有类似如下的成对调用CrossCoreSetFlag和CrossCoreWaitFlag // modeId必须配置为4flagId要一致 if ASCEND_IS_AIV { if (blockIdx % 2 0) { AscendC::CrossCoreSetFlag4, PIPE_MTE3(0); // 待AIV0上前置PIPE_MTE3流水任务完成后通知调度器。对于flagIdAIV0上的0-15对应AIC上的0-15。 } if (blockIdx % 2 1) { AscendC::CrossCoreSetFlag4, PIPE_MTE3(0); // 待AIV1上前置PIPE_MTE3流水任务完成后通知调度器。对于flagIdAIV1上的0-15对应AIC上的16-31。 } } if ASCEND_IS_AIC { AscendC::CrossCoreWaitFlag4, PIPE_FIX(0); // 阻塞后续PIPE_FIX流水指令直到该AI Core中的AIV0都完成前置PIPE_MTE3流水调度器更新flagId0的计数器后AIC解除阻塞 ... AscendC::CrossCoreWaitFlag4, PIPE_FIX(16); // 阻塞后续PIPE_FIX流水指令直到该AI Core中的AIV1都完成前置PIPE_MTE3流水调度器更新flagId16的计数器后AIC解除阻塞 ... }以图4为例演示M2时1个AI Core中AIV1与AIC进行同步AIV1-2发起CrossCoreSetFlag。AIC 1中在执行CrossCoreWaitFlag后此时AIC 1 flagId0的计数器为0后续所有指令全部被阻塞需要等到1个AIV执行完CrossCoreSetFlag。AIV 1-1不需要执行CrossCoreSetFlag。AIV 1-2的PIPE_MTE3指令全部执行完毕后CrossCoreSetFlag生效。此时调度模块感知1个AIV已执行完CrossCoreSetFlag因此将AIC 1 flagId0的计数器值增加为1。AIC 1检测到对应的flagId0的计数器变为1则AIC 1核解除阻塞继续执行后续PIPE_FIX的指令并且将计数器值减去1。图4模式4单AI Core中AIC与单个AIV同步AIV进行CrossCoreSetFlag【免费下载链接】asc-devkit本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言原生支持C和C标准规范主要由类库和语言扩展层构成提供多层级API满足多维场景算子开发诉求。项目地址: https://gitcode.com/cann/asc-devkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考