Block Scheduler StreamK【免费下载链接】ops-tensorops-tensor 是 CANN Compute Architecture for Neural Networks算子库中提供张量类计算的基础算子库采用模块化设计支持灵活的算子开发和管理。项目地址: https://gitcode.com/cann/ops-tensor代码位置功能说明StreamK 调度器支持 DPSK 混合策略。将问题规模切分为 DPData Parallel模式和 SKStreamK模式的 tile适用于 StreamK Kernel 的 AICAIV 双核协同计算场景。继承自Block Scheduler 公共框架特殊约束DPSK 混合策略StreamK 调度器将 tile 分为两种模式DPData Parallel模式完整 tile每个核独立处理完整的 (m, n) tile结果直接输出到 GMSKStreamK模式K 轴切分 tile多个核协同处理一个 (m, n) tile 的不同 K 切分结果输出到 workspaceDP 模式 tiletile 数量totalMNTileNumInDP_ mTileNum_ × nTileNum_ - tailMNTileNum每个核处理完整的 (m, n) tileK 轴不切分输出目标GM通过 BlockMmad 输出SK 模式 tiletile 数量tailMNTileNum × skKTileNum每个核处理一个 (m, n) tile 的部分 K 切分K 切分数量skKTileNum_ CeilDiv(k_, skSingleCoreK_)输出目标workspace通过 BlockMmad 输出tile 索引分配tileIdx 判断 DP 模式CeilDiv((tileIdx 1), usedCoreNum_) CeilDiv(tileNum_, usedCoreNum_) SK 模式CeilDiv((tileIdx 1), usedCoreNum_) CeilDiv(tileNum_, usedCoreNum_)Batch 支持支持 Batch 场景tile 数量tileNum_ × batch_Batch 索引在 tile 循环中由 Kernel 层处理Z 型扫描与 Swat 调度器相同使用 Z 型扫描策略WINDOW_LEN 4扫描窗口大小正向扫描偶数行rowIdx % 2 0反向扫描奇数行rowIdx % 2 ! 0HF32 模式支持 HF32 计算模式isHf32_HF32 标志从 params 传入GetHf32Flag()返回 HF32 标志特殊静态常量常量说明WINDOW_LENZ 型扫描窗口长度4特殊类型别名类型说明BlockShapeBlock 形状Shapeint64_t, int64_t, int64_t, int64_tBlockCoordBlock 坐标Coordint64_t, int64_t, int64_t, int64_t(mTileIdx, nTileIdx, kTileIdx, 0)ProblemShape问题规模类型模板参数特殊数据结构Paramsstruct Params { int64_t usedCoreNum{0}; // 使用的核数 int64_t baseM{0}; // L0 M 维度 base 大小 int64_t baseN{0}; // L0 N 维度 base 大小 int64_t baseK{0}; // L0 K 维度 base 大小固定 32 int64_t singleCoreK{0}; // SK 模式下单核处理的 K 大小 int64_t kL1{0}; // L1 K 维度大小 int64_t isHf32{0}; // HF32 模式标志 };说明usedCoreNum参与计算的 AIC 核数量singleCoreKSK 模式下每个核处理的 K 维大小用于 K 轴切分baseK固定为 32需根据 baseM, baseN, L0 调整特殊成员变量变量说明usedCoreNum_使用的核数skKTileNum_SK 模式 K 轴 tile 数量tileNum_总 tile 数量DP tile SK tiletotalMNTileNumInDP_DP 模式 tile 数量mTileIdx_当前 M 轴 tile 索引nTileIdx_当前 N 轴 tile 索引kTileIdx_当前 K 轴切分索引SK 模式curKTileNum_当前 K 轴 tile 数量DP1, SKskKTileNum_skSingleCoreK_SK 模式单核 K 大小isHf32_HF32 模式标志特殊成员方法构造函数__aicore__ inline BlockSchedulerStreamK(const ProblemShape shape, const Params params)功能初始化 BlockSchedulerStreamK计算 DPSK 混合 tile 切分。 参数说明 | 参数 | 类型 | 说明 | |------|------|------| | shape | ProblemShape | 问题规模(m, n, k, batch)| | params | Params | 调度参数usedCoreNum, baseM, baseN, baseK, singleCoreK, kL1, isHf32 |执行流程设置问题规模m_,n_,k_,batch_设置 L1/L0 形状mL1_ baseM_,nL1_ baseN_,skSingleCoreK_ singleCoreK,kL1_,baseK_计算 tile 数量mTileNum_ CeilDiv(m_, mL1_),nTileNum_ CeilDiv(n_, nL1_),skKTileNum_ CeilDiv(k_, skSingleCoreK_)计算 DPSK tiletailMNTileNum (mTileNum_ × nTileNum_) % usedCoreNum_SK 模式 tile 数量totalMNTileNumInDP_ mTileNum_ × nTileNum_ - tailMNTileNumDP 模式 tile 数量tileNum_ totalMNTileNumInDP_ tailMNTileNum × skKTileNum_总 tile 数量GetTotalTileNum__aicore__ inline int64_t GetTotalTileNum()功能返回总 tile 数量tileNum_ × batch_。GetHf32Flag__aicore__ inline int64_t GetHf32Flag()功能返回 HF32 模式标志isHf32_。GetTileL1Shape__aicore__ inline Shapeint64_t, int64_t, int64_t, int64_t GetTileL1Shape()功能返回 L1 tile 形状{mL1_, nL1_, kL1_, 1}。GetTileL0Shape__aicore__ inline Shapeint64_t, int64_t, int64_t, int64_t GetTileL0Shape()功能返回 L0 tile 形状{baseM_, baseN_, baseK_, 1}。GetMNKTileNum__aicore__ inline Shapeint64_t, int64_t, int64_t, int64_t GetMNKTileNum()功能返回 M/N/K tile 数量{mTileNum_, nTileNum_, skKTileNum_, 1}。GetBlockNum__aicore__ inline int64_t GetBlockNum(int64_t blockNum)功能返回实际使用的 Block 数量不超过 tile 总数。GetCurKSingleCore__aicore__ inline int64_t GetCurKSingleCore(int64_t tileIdx)功能返回当前 tile 的单核 K 大小。 参数说明 | 参数 | 类型 | 说明 | |------|------|------| | tileIdx | int64_t | tile 索引 |返回值DP 模式k_完整 KSK 模式skSingleCoreK_切分 KGetSingleCoreShape__aicore__ inline BlockShape GetSingleCoreShape(int64_t tileIdx)功能返回当前 tile 的单核形状。 参数说明 | 参数 | 类型 | 说明 | |------|------|------| | tileIdx | int64_t | tile 索引 |返回值BlockShape {blkM, blkN, blkK, 0}特殊逻辑尾块判断mTileIdx_ (mTileNum_ - 1)或nTileIdx_ (nTileNum_ - 1)K 切分尾块kTileIdx_ (curKTileNum_ - 1)DP 模式blkK k_完整 KSK 模式blkK skSingleCoreK_或tailSingleCoreKGetSingleCoreCoord__aicore__ inline BlockCoord GetSingleCoreCoord(int64_t tileIdx)功能返回当前 tile 的单核坐标。 参数说明 | 参数 | 类型 | 说明 | |------|------|------| | tileIdx | int64_t | tile 索引 |返回值BlockCoord {mTileIdx_, nTileIdx_, kTileIdx_, 0}说明K 轴索引kTileIdx_仅在 SK 模式有效DP 模式为 0。CheckIsSkScene__aicore__ inline bool CheckIsSkScene(int64_t tileIdx)功能判断当前 tile 是否为 SK 模式。 参数说明 | 参数 | 类型 | 说明 | |------|------|------| | tileIdx | int64_t | tile 索引 |返回值trueSK 模式K 轴切分falseDP 模式完整 tile判断逻辑CeilDiv((tileIdx 1), usedCoreNum_) CeilDiv(tileNum_, usedCoreNum_)UpdateMNTileIdx__aicore__ inline void UpdateMNTileIdx(int64_t tileIdx)功能更新当前 tile 的 M/N/K tile 索引。 参数说明 | 参数 | 类型 | 说明 | |------|------|------| | tileIdx | int64_t | tile 索引 |执行流程判断 DP/SK 模式CheckIsSkScene(tileIdx)设置 K 轴 tile 数量curKTileNum_ (SK ? skKTileNum_ : 1)计算 mnIdxInCurLoopSK 模式kTileIdx_ (tileIdx % usedCoreNum_) % curKTileNum_,mnIdxInCurLoop (tileIdx % usedCoreNum_) / curKTileNum_ totalMNTileNumInDP_DP 模式kTileIdx_ 0,mnIdxInCurLoop tileIdx / curKTileNum_Z 型扫描计算mTileIdx_,nTileIdx_反向扫描奇数行反向nTileIdx_ nTileNum_ - 1 - nTileIdx_调用示例组件组装using ProblemShape Shapeint64_t, int64_t, int64_t, int64_t; using BlockScheduler Blaze::Gemm::Block::BlockSchedulerStreamKProblemShape;参数准备BlockScheduler::Params params { usedCoreNum, // 使用的核数如 8 baseM, // L0 M 维度 base如 256 baseN, // L0 N 维度 base如 256 baseK, // L0 K 维度 base如 32 singleCoreK, // SK 模式单核 K 大小如 k_ / 4 kL1, // L1 K 维度如 baseK isHf32 // HF32 模式0 或 1 };组件初始化ProblemShape shape{m, n, k, batch}; BlockScheduler scheduler(shape, params);获取 tile 数量int64_t tileNum scheduler.GetTotalTileNum(); int64_t blockNum scheduler.GetBlockNum(GetBlockNum()); for (int64_t tileIdx GetBlockIdx(); tileIdx tileNum; tileIdx blockNum) { // 处理 tile }判断 DP/SK 模式bool isSkScene scheduler.CheckIsSkScene(tileIdx); if (isSkScene) { // SK 模式输出到 workspace } else { // DP 模式输出到 GM }获取单核形状auto singleCoreShape scheduler.GetSingleCoreShape(tileIdx); int64_t blkM Get0(singleCoreShape); int64_t blkN Get1(singleCoreShape); int64_t blkK Get2(singleCoreShape);获取单核坐标auto singleCoreCoord scheduler.GetSingleCoreCoord(tileIdx); int64_t mTileIdx Get0(singleCoreCoord); int64_t nTileIdx Get1(singleCoreCoord); int64_t kTileIdx Get2(singleCoreCoord); // SK 模式有效获取当前 K 大小int64_t curK scheduler.GetCurKSingleCore(tileIdx); // DP 模式curK k_ // SK 模式curK skSingleCoreK_获取配置int64_t hf32Flag scheduler.GetHf32Flag(); auto tileL1Shape scheduler.GetTileL1Shape(); auto tileL0Shape scheduler.GetTileL0Shape(); auto mnkTileNum scheduler.GetMNKTileNum();数据流DPSK 混合策略流程问题规模 (m, n, k, batch) ↓ tile 切分 (mTileNum, nTileNum, skKTileNum) ↓ DP tile 数量 mTileNum × nTileNum - tailMNTileNum ↓ SK tile 数量 tailMNTileNum × skKTileNum ↓ 总 tile 数量 DP tile SK tile ↓ tile 索引判断 (CheckIsSkScene) ↓ DP 模式完整 tile输出到 GM SK 模式K 轴切分输出到 workspaceDP 模式流程tileIdx 判断CeilDiv((tileIdx 1), usedCoreNum) CeilDiv(tileNum, usedCoreNum) ↓ curKTileNum 1不切分 K ↓ kTileIdx 0 ↓ GetSingleCoreShapeblkK k_完整 K ↓ BlockMmad输出到 GMSK 模式流程tileIdx 判断CeilDiv((tileIdx 1), usedCoreNum) CeilDiv(tileNum, usedCoreNum) ↓ curKTileNum skKTileNumK 轴切分 ↓ kTileIdx (tileIdx % usedCoreNum) % curKTileNum ↓ GetSingleCoreShapeblkK skSingleCoreK_ 或 tailSingleCoreK ↓ BlockMmad输出到 workspace ↓ BlockEpilogueAIVworkspace 汇聚 → GMZ 型扫描流程mnIdxInCurLoopDP/SK 模式的 MN 索引 ↓ rowIdx mnIdxInCurLoop / nTileNum / mainWindow ↓ rowIdx mainRowmTileIdx rowIdx × mainWindow mnIdxInCurLoop % mainWindow ↓ rowIdx mainRow尾窗口计算 ↓ rowIdx % 2 ! 0反向扫描nTileIdx nTileNum - 1 - nTileIdx性能优化建议usedCoreNum 配置建议值根据实际 AIC 核数量设置如 8、16SK 模式比例tailMNTileNum (mTileNum × nTileNum) % usedCoreNum优化调整 usedCoreNum 以减少 SK 模式 tile 数量singleCoreK 配置建议值约为k_ / 4平衡 K 轴切分数量SK tile 数量skKTileNum CeilDiv(k_, singleCoreK)优化调整 singleCoreK 以减少 K 轴切分数量DPSK 比例配置DP 模式totalMNTileNumInDP_ mTileNum × nTileNum - tailMNTileNumSK 模式tailMNTileNum × skKTileNum优化调整 mTileNum, nTileNum, usedCoreNum 以增加 DP 模式比例tile 形状配置mL1 baseML1 M 维度等于 L0 base如 256nL1 baseNL1 N 维度等于 L0 base如 256kL1L1 K 维度如 baseK 或更大优化使用性能最优的 tile 形状HF32 模式配置isHf32 1启用 HF32 计算模式适用场景需要高精度计算的 FP32 场景适用场景StreamK KernelAIC AIV 双核协同大矩阵场景(m × n × k) 较大需要多核并行K 轴切分场景K 维度远大于 M/N高并行度场景需要充分利用 AIC 和 AIV 双核【免费下载链接】ops-tensorops-tensor 是 CANN Compute Architecture for Neural Networks算子库中提供张量类计算的基础算子库采用模块化设计支持灵活的算子开发和管理。项目地址: https://gitcode.com/cann/ops-tensor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考