CrossCoreWaitFlag(ISASI)

产品支持情况

产品

是否支持

Ascend 950PR/Ascend 950DT

Atlas A3 训练系列产品/Atlas A3 推理系列产品

Atlas A2 训练系列产品/Atlas A2 推理系列产品

Atlas 200I/500 A2 推理产品

x

Atlas 推理系列产品AI Core

x

Atlas 推理系列产品Vector Core

x

Atlas 训练系列产品

x

功能说明

头文件路径为:"basic_api/kernel_operator_block_sync_intf.h"

在核间同步场景中,CrossCoreSetFlag接口和CrossCoreWaitFlag接口配对工作,具体功能请参考CrossCoreSetFlag

函数原型

template <uint8_t modeId = 0, pipe_t pipe = PIPE_S>
__aicore__ inline void CrossCoreWaitFlag(uint16_t flagId)

参数说明

表 1 模板参数说明

参数名 描述
modeId 核间同步的模式,支持的取值如下:
• 模式0:AI Core核间的同步控制(所有AIC之间或者所有AIV之间)。
• 模式1:AI Core内部,Vector核(AIV)之间的同步控制。
• 模式2:AI Core内部,Cube核(AIC)与所有Vector核(AIV)之间的同步控制。
• 模式4:AI Core内部,AIC与单个AIV之间的同步控制。AIV0与AIV1可单独触发AIC等待。
各个模式支持的对应Kernel类型请参照表3。
pipe 设置这条指令所在的流水类型。模式0、1、2支持的流水类型为PIPE_V、PIPE_M、PIPE_MTE1、PIPE_MTE2、PIPE_MTE3、PIPE_FIX,不支持PIPE_S和PIPE_ALL。
针对Ascend 950PR/Ascend 950DT,模式4相较其他三种模式额外支持PIPE_S流水类型。

表 2 参数说明

参数名 输入/输出 描述
flagId 输入 核间同步的标记。
• Ascend 950PR/Ascend 950DT,取值范围如下:
  • AIV0发起的flagId 0-10的CrossCoreSetFlag操作对应AIC CrossCoreWaitFlag中flagId 0-10的操作。
  • AIV1发起的flagId 0-10的CrossCoreSetFlag操作对应AIC CrossCoreWaitFlag中flagId 16-26的操作。
  • AIC发起的flagId 0-10的CrossCoreSetFlag操作对应AIV0 CrossCoreWaitFlag中flagId 0-10的操作。
  • AIC发起的flagId 16-26的CrossCoreSetFlag操作对应AIV1 CrossCoreWaitFlag中flagId 0-10的操作。
• Atlas A3 训练系列产品/Atlas A3 推理系列产品,取值范围是0-10。
• Atlas A2 训练系列产品/Atlas A2 推理系列产品,取值范围是0-10。

返回值说明

约束说明

  • 不同产品版本下,CrossCoreWaitFlag接口对核间同步模式和流水类型的配置支持情况如下:

    • Ascend 950PR/Ascend 950DT,硬件支持配置核间同步模式和流水类型,模板参数modeId和pipe生效。模式0、1、2支持的流水类型为PIPE_V、PIPE_M、PIPE_MTE1、PIPE_MTE2、PIPE_MTE3、PIPE_FIX;模式4相较其他三种模式额外支持PIPE_S流水类型。
    • Atlas A3 训练系列产品/Atlas A3 推理系列产品,硬件不支持配置核间同步模式和流水类型,传入该接口的模板参数modeId和pipe不生效。
    • Atlas A2 训练系列产品/Atlas A2 推理系列产品,硬件不支持配置核间同步模式和流水类型,传入该接口的模板参数modeId和pipe不生效。
  • 由于当Kernel类型为KERNEL_TYPE_AIC_ONLY或 KERNEL_TYPE_AIV_ONLY时,硬件不会开启调度模块,也就无法正常进行核间同步,因此不同的同步模式配置Kernel类型函数修饰符的情况如不:

    • 在纯Vector/Cube场景下(模式0或模式1),建议设置Kernel类型为KERNEL_TYPE_MIX_AIV_1_0或KERNEL_TYPE_MIX_AIC_1_0,其它支持的Kernel类型请参考表3。

    • 对于Vector和Cube混合场景(模式2),需根据AI Core中AIC和AIV的比例灵活配置Kernel类型,不同模式支持的函数修饰符和Kernel类型请参照表3。

      表 3 模式与支持的Kernel类型配置

      模式 支持的函数修饰符 支持的Kernel类型配置
      0 __mix__(0, 1),__mix__(1, 0), __mix__(1, 1),__mix__(1, 2) KERNEL_TYPE_MIX_AIV_1_0, KERNEL_TYPE_MIX_AIC_1_0,KERNEL_TYPE_MIX_AIC_1_1, KERNEL_TYPE_MIX_AIC_1_2
      1 __mix__(1, 1),__mix__(1, 2) KERNEL_TYPE_MIX_AIC_1_1, KERNEL_TYPE_MIX_AIC_1_2
      2 __mix__(1, 1),__mix__(1, 2) KERNEL_TYPE_MIX_AIC_1_1, KERNEL_TYPE_MIX_AIC_1_2
  • CrossCoreWaitFlag必须与CrossCoreSetFlag接口配合使用,避免计算核一直处于阻塞阶段。

  • 接口使用模式0、1、2,需要避免flagId使用冲突:

    • Matmul高阶API内部实现中使用了CrossCoreSetFlag进行核间同步控制,所以不建议开发者同时使用CrossCoreSetFlag和Matmul高阶API,否则会有flagId冲突的风险。Matmul高阶API内部占用的flagId范围与定义的Matmul对象数目相关,假设定义了N个Matmul对象数目,Matmul高阶API内部占用的flagId范围为[0, 2 * N - 1]。Matmul最多支持定义4个对象,此时flagId占用范围为[0,7]。

    • SyncAll硬件同步接口内部实现中使用了CrossCoreSetFlag进行核间同步控制,所以不建议开发者同时使用CrossCoreSetFlag和SyncAll硬件同步接口,否则会有flagID冲突的风险。SyncAll硬件同步接口flagId占用范围为[11-14]。

  • flagId相关的约束:

    • 对于模式0、1、2,每个AIC和每个AIV都各自有16个flagId,支持的取值范围为0-15。如果flagId的值超出该范围,则会取截取最低位4bit为准。
    • 每个flagId有个对应计数器,当调用CrossCoreWaitFlag时,若计数器值为0则会阻塞后续指令下发,已下发指令可正常执行;当调度模块感知到核间同步(CrossCoreSetFlag)全部完成后,会将对应CrossCoreWaitFlag的计数器的值增加1。此时,计数器值为非0,阻塞解除,并且将对应计数器的值减去1进行还原。具体执行逻辑与细节可以参考关键特性说明。flagId对应的计数器计数范围为0-15。如果计数器的值超出该范围,则会异常报错,中断流程。
  • 模式0、1、2下,同一个flagId用于不同核间同步模式的约束:

    • 同一核上,若同一个flagId需用于不同核间同步模式,须在模式切换前完成前一个模式的所有同步操作——即确保该flagId关联的所有CrossCoreSetFlag与配套CrossCoreWaitFlag调用均已执行完毕。
    • 对于不同的核,可以直接将同一flagId用于不同的核间同步模式,具体包括以下2种场景:
      • 多个AI Core之间,使用flagId=0同步所有的AIC(模式0);单个AI Core内,使用flagId=0同步所有AIV(模式1)。
      • 单个AI Core内,使用flagId=0同步所有AIV(模式1);另一个AI Core内,使用flagId=0同步AIC与所有AIV(模式2)。
  • 使用该接口模式0时,建议开启batchmode模式,使算子独占全部所需核资源,否则可能因满足以下条件导致死锁:

    • 多流并发场景(≥2条执行流)。
    • ≥2个算子并发执行。
    • 所有并发算子的核数总和超过物理核数。
    • ≥2个并发算子使用了核间同步功能。

    具体而言,在多流场景下,某条流的核间同步算子虽分配到n个物理核,但可能仅有n-m个核先被调度执行,而其余m个核因被其他流的核间同步算子抢占而尚未启动。先启动的n-m个核执行到核间同步时等待剩余m核完成,而剩余m核因被其他流的核间同步算子占用而无法释放,形成死锁。

    Kernel直调场景下通过__schedmode__(mode)限定符来设置batchmode模式;工程化算子开发场景下,通过TilingContext的SetScheduleMode接口来设置batchmode模式,具体请参考《基础数据结构和接口》

调用示例

表3 样例描述

SCENARIO_NUM取值 业务场景 使用的同步模式
0 纯Vector计算场景(16个AIV) mode0(AIV全核同步)
1 纯Vector计算场景(2个AIV) mode1
2 Cube与Vector融合计算场景 mode2(AIC等AIV)、mode2(AIV等AIC)、mode0(AIC全核同步)

如上表所示,当SCENARIO_NUM取不同值时,会分别演示纯Vector计算场景和Cube与Vector融合计算场景下三种同步模式的具体使用方法,下面展示了纯Vector计算场景的部分调用代码:

    AscendC::Muls(xLocal, xLocal, float(AscendC::GetBlockIdx()), this->blockLength);
    AscendC::SetFlag<AscendC::HardEvent::V_MTE3>(EVENT_ID0);
    AscendC::WaitFlag<AscendC::HardEvent::V_MTE3>(EVENT_ID0);

    // UB到GM搬运启用原子累加。
    AscendC::SetAtomicAdd<float>();
    // DataCopy属于PIPE_MTE3流水操作。
    AscendC::DataCopy(atomicResultGm, xLocal, this->blockLength);
    // 当本AIV完成前置PIPE_MTE3(DataCopy)流水操作后,通知其他AIV核,本AIV已经完成。
    AscendC::CrossCoreSetFlag<0, PIPE_MTE3>(0);
    // 阻塞本AIV继续往下执行指令,直到其他AIV全部都完成PIPE_MTE3流水操作,才解除阻塞往下执行。
    AscendC::CrossCoreWaitFlag(0);
    // 关闭原子累加。
    AscendC::SetAtomicNone();

    if (AscendC::GetBlockIdx() == 0) {
        AscendC::DataCopy(yLocal, atomicResultGm, this->blockLength);
        AscendC::SetFlag<AscendC::HardEvent::MTE2_MTE3>(EVENT_ID0);
        AscendC::WaitFlag<AscendC::HardEvent::MTE2_MTE3>(EVENT_ID0);
        AscendC::DataCopy(atomicResultGm, yLocal, this->blockLength);
        return;
    }

完整样例请参考CrossCoreSetFlag和CrossCoreWaitFlag核间同步样例