当前位置: 首页 > news >正文

CANN/asc-devkit CubeResGroupHandle使用说明

CubeResGroupHandle使用说明

CubeResGroupHandle用于在分离模式下对AI Core计算资源分组。分组后,开发者可以对不同的分组指定不同的计算任务。一个AI Core分组可包含多个AIV和AIC,AIV和AIC之间采取Client和Server架构进行任务处理。AIV为Client,每一个Cube计算任务为一个消息,AIV发送消息至消息队列,AIC作为Server,遍历消息队列的消息,根据消息类型及内容执行对应的计算任务。一个CubeResGroupHandle中可以有一个或多个AIC,同一个AIC只能属于一个CubeResGroupHandle,AIV无此限制,即同一个AIV可以属于多个CubeResGroupHandle。

如下图所示,CubeResGroupHandle1中有2个AIC,10个AIV,AIC为Block0和Block1。其中Block0与Queue0、Queue1、Queue2、Queue3、Queue4进行通信,Block1与Queue 5、Queue 6、Queue 7、Queue 8、Queue9进行通信。每一个消息队列对应一个AIV,消息队列的深度固定为4,即一次性最多可以容纳4个消息。CubeResGroupHandle2的消息队列个数为12,表明有12个AIV。CubeResGroupHandle的消息处理顺序如CubeResGroupHandle2中黑色箭头所示。

图 1基于CubeResGroupHandle的AI Core计算资源分组通信示意图
![](https://raw.gitcode.com/cann/asc-devkit/raw/68eb55191616e7a7b08961a5c82a706272353b5f/docs/api/figures/基于CubeResGroupHandle的AI-Core计算资源分组通信示意图.png "基于CubeResGroupHandle的AI-Core计算资源分组通信示意图"?utm_source=gitcode_repo_files)

基于CubeResGroupHandle实现AI Core计算资源分组步骤如下:

  1. 创建AIC上所需要的计算对象类型。

  2. 创建通信区域描述KfcWorkspace,用于记录通信消息Msg的地址分配。

  3. 自定义消息结构体,用于通信。

  4. 自定义回调计算结构体,根据实际业务场景实现Init函数和Call函数。

  5. 创建CubeResGroupHandle。

  6. 绑定AIV到CubeResGroupHandle。

  7. 收发消息。

  8. AIV退出消息队列。

  9. 创建AIC上所需要的计算对象类型。

    用户根据实际需求,自定义AIC所需要的计算对象类型,或者高阶API已提供的Matmul类型。例如,创建Matmul类型如下,其中A_TYPE、B_TYPE、 C_TYPE、BIAS_TYPE、CFG_NORM等含义请参考Matmul模板参数。

    // A_TYPE, B_TYPE, C_TYPE, BIAS_TYPE, CFG_NORM根据实际需求场景构造 using MatmulApiType = MatmulImpl<A_TYPE, B_TYPE, C_TYPE, C_TYPE, CFG_NORM>;
  10. 创建KfcWorkspace。

    使用KfcWorkspace管理不同CubeResGrouphandle的消息通信区的划分。

    // 创建KfcWorkspace对象前,需要对该workspaceGM清零 KfcWorkspace desc(workspaceGM);
  11. 自定义消息结构体。

    用户需要自行构造消息结构体CubeMsgBody,用于AIV向AIC发送通信消息。构造的CubeMsgBody必须64字节对齐,该结构体最前面需要定义2字节的CubeGroupMsgHead,使消息收发机制正常运行,CubeGroupMsgHead结构定义请参考表2。除2字节的CubeGroupMsgHead外,其余参数根据业务需求自行构造。

    表 1CubeMsgBody消息结构体

    参数名称

    含义

    CubeMsgBody

    用户自定义的消息结构体。结构体名称可自定义,结构体大小需要64字节对齐。

    // 这里提供64B对齐的结构体示例,用户实际使用时,除CubeGroupMsgHead外,其他参数个数及参数类型可自行构造 struct CubeMsgBody { CubeGroupMsgHead head; // 2B,需放在结构体最前面, 自定义的CubeMsgBody中,CubeGroupMsgHead的变量名需设置为head,否则会编译报错。 uint8_t funcID; uint8_t skipCnt; uint32_t value; bool isTransA; bool isTransB; bool isAtomic; bool isLast; int32_t tailM; int32_t tailN; int32_t tailK; uint64_t aAddr; uint64_t bAddr; uint64_t cAddr; uint64_t aGap; uint64_t bGap; }

    表 2CubeGroupMsgHead结构体参数定义

    参数名称

    含义

    msgState

    表明该位置的消息状态。参数取值如下:

    • CubeMsgState::FREE:表明该位置还未填写消息,可执行AllocMessage。
    • CubeMsgState::VALID:表明该位置已经含有AIV发送的消息,待AIC接收执行。
    • CubeMsgState::QUIT:表明该位置的消息为通知AIC有AIV将退出流程。
    • CubeMsgState::FAKE:表明该位置的消息为假消息。在消息合并场景,被跳过处理任务的AIV需要发送假消息,消息合并场景请参考PostFakeMsg中的介绍。

    aivID

    发送消息的AIV的序号。

  12. 自定义回调计算结构体,根据实际业务场景实现Init函数和Call函数。

    template<class MatmulApiCfg, class CubeMsgBody> struct NormalCallbackFuncs { __aicore__ inline static void Call(MatmulApiCfg &mm, __gm__ CubeMsgBody *rcvMsg, CubeResGroupHandle<CubeMsgBody> &handle){ // 用户自行实现逻辑 }; __aicore__ inline static void Init(NormalCallbackFuncs<MatmulApiCfg, CubeMsgBody> &foo, MatmulApiCfg &mm, GM_ADDR tilingGM){ // 用户自行实现逻辑 }; };

    计算逻辑结构体的模板参数请参考表3。

    表 3模板参数说明

    参数

    说明

    MatmulApiCfg

    用户自定义的AIC上计算所需要对象的数据类型,参考步骤1,该模板参数必须填入。

    CubeMsgBody

    用户自定义的消息结构体,该模板参数必须填入。

    用户自定义回调计算结构体中需要包含固定的Init函数和Call函数,函数原型如下所示。其中,Init函数的参数说明请参考表4,Call函数的参数说明请参考表5。

    // 该函数的参数和名称为固定格式,函数实现根据业务逻辑自行实现。 __aicore__ inline static void Init(MyCallbackFunc<MatmulApiCfg, CubeMsgBody> &myCallBack, MatmulApiCfg &mm, GM_ADDR tilingGM){ // 用户自行实现内部逻辑 }

    表 4Init函数参数说明

    参数

    输入/输出

    说明

    myCallBack

    输入

    用户自定义的带模板参数的回调计算结构体。

    mm

    输入

    AIC上计算对象,多为Matmul对象。

    tilingGM

    输入

    用户传入的tiling指针。

    // 该函数的参数和名称为固定格式,函数实现根据业务逻辑自行实现。 __aicore__ inline static void Call(MatmulApiCfg &mm, __gm__ CubeMsgBody *rcvMsg, CubeResGroupHandle<CubeMsgBody> &handle){ // 用户自行实现内部逻辑 }

    表 5Call函数参数说明

    参数

    输入/输出

    说明

    mm

    输入

    AIC上计算对象,多为Matmul对象。

    rcvMsg

    输入

    用户自定义的消息结构体指针。

    handle

    输入

    分组管理Handle,用户调用其接口进行收发消息,释放消息等。

    某算子的回调计算结构体的代码示例如下。

    // 用户自定义的回调计算逻辑 template<class MatmulApiCfg, typename CubeMsgBody> struct MyCallbackFunc { template<int32_t funcId> __aicore__ inline static typename IsEqual<funcId, 0>::Type CubeGroupCallBack(MatmulApiCfg &mm, __gm__ CubeMsgBody *rcvMsg, CubeResGroupHandle<CubeMsgBody> &handle) { GlobalTensor<int64_t> msgGlobal; msgGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ int64_t *> (rcvMsg) + sizeof(int64_t)); DataCacheCleanAndInvalid<int64_t, CacheLine::SINGLE_CACHE_LINE, DcciDst::CACHELINE_OUT> (msgGlobal); using SrcAT = typename MatmulApiCfg::AType::T; auto skipNum = 0; for (int i = 0; i < skipNum + 1; ++i) { auto tmpId = handle.FreeMessage(rcvMsg + i); // msgPtr process is complete } handle.SetSkipMsg(skipNum); } template<int32_t funcId> __aicore__ inline static typename IsEqual<funcId, 1>::Type CubeGroupCallBack(MatmulApiCfg &mm, __gm__ CubeMsgBody *rcvMsg, CubeResGroupHandle<CubeMsgBody> &handle) { GlobalTensor<int64_t> msgGlobal; msgGlobal.SetGlobalBuffer(reinterpret_cast<__gm__ int64_t *> (rcvMsg) + sizeof(int64_t)); DataCacheCleanAndInvalid<int64_t, CacheLine::SINGLE_CACHE_LINE, DcciDst::CACHELINE_OUT> (msgGlobal); using SrcAT = typename MatmulApiCfg::AType::T; LocalTensor<SrcAT> tensor_temp; auto skipNum = 3; auto tmpId = handle.FreeMessage(rcvMsg, CubeMsgState::VALID); for (int i = 1; i < skipNum + 1; ++i) { auto tmpId = handle.FreeMessage(rcvMsg + i, CubeMsgState::FAKE); } handle.SetSkipMsg(skipNum); // notify the cube not to process } __aicore__ inline static void Call(MatmulApiCfg &mm, __gm__ CubeMsgBody *rcvMsg, CubeResGroupHandle<CubeMsgBody> &handle) { if (rcvMsg->funcId == 0) { CubeGroupCallBack<0> (mm, rcvMsg, handle); } else if(rcvMsg->funcId == 1) { CubeGroupCallBack<1> (mm, rcvMsg, handle); } } __aicore__ inline static void Init(MyCallbackFunc<MatmulApiCfg, CubeMsgBody> &foo, MatmulApiCfg &mm, GM_ADDR tilingGM) { auto tempTilingGM = (__gm__ uint32_t*)tilingGM; auto tempTiling = (uint32_t*)&(foo.tiling); for (int i = 0; i < sizeof(TCubeTiling) / sizeof(int32_t); ++i, ++tempTilingGM, ++tempTiling) { *tempTiling = *tempTilingGM; } mm.SetSubBlockIdx(0); mm.Init(&foo.tiling, GetTPipePtr()); } TCubeTiling tiling; };
  13. 创建CubeResGroupHandle。

    用户使用CreateCubeResGroup接口创建一个或多个CubeResGroupHandle。

    /* * groupID为用户自定义的CreateCubeResGroup的groupID * MatmulApiType为定义好的AIC上计算对象的类型 * MyCallbackFunc为定义好的自定义回调计算结构体 * CubeMsgBody为自定义消息结构体 * desc为用户初始化好的通信区域描述 * groupID为1,blockStart为0,blockSize为12,msgQueueSize为48,tilingGm为指针,存储了用户在AIC上所需要的tiling信息 */ auto handle = AscendC::CreateCubeResGroup<groupID, MatmulApiType, MyCallbackFunc, CubeMsgBody>(desc, 0, 12, 48, tilingGM);
  14. 绑定AIV到CubeResGroupHandle。

    绑定AIV和消息队列序号。注意:消息队列序号queIdx小于该CubeGroupHandle的消息队列总数,每个AIV需要传入不同的queIdx。handle为步骤5中CreateCubeResGroup创建的CubeResGroupHandle对象。

    handle.AssignQueue(queIdx);
  15. AIV发消息。

    用户调用AllocMessage, PostMessage等接口进行消息的收发。其中,调用AllocMessage获取消息结构体指针,通过PostMessage发送消息,在消息合并场景调用PostFakeMessage发送假消息,示例如下。

    CubeGroupMsgHead head = {CubeMsgState::VALID, (uint8_t)queIdx}; CubeMsgBody aCubeMsgBody {head, 0, 0, 0, false, false, false, false, 0, 0, 0, 0, 0, 0, 0, 0}; CubeMsgBody bCubeMsgBody {head, 1, 0, 0, false, false, false, false, 0, 0, 0, 0, 0, 0, 0, 0}; auto offset = 0; if (GetBlockIdx() == 0) { auto msgPtr = handle.template AllocMessage(); // alloc for queue space offset = handle.template PostMessage(msgPtr, bCubeMsgBody); // post true msgPtr bool waitState = handle.template Wait<true> (offset); // wait until the msgPtr is processed } else if (GetBlockIdx() < 4) { auto msgPtr = handle.AllocMessage(); offset = handle.PostFakeMsg(msgPtr); // post fake msgPtr bool waitState = handle.template Wait<true> (offset); // wait until the msgPtr is processed } else { auto msgPtr = handle.template AllocMessage(); offset = handle.template PostMessage(msgPtr, aCubeMsgBody); bool waitState = handle.template Wait<true> (offset); // wait until the msgPtr is processed }
  16. AIV退出消息队列。

    调用AllocMessage获取消息结构体指针后,通过SendQuitMsg发送当前消息队列退出。

    auto msgPtr = handle.AllocMessage(); // 获取消息空间指针msgPtr handle.SetQuit(msgPtr); // 发送退出消息
http://www.jsqmd.com/news/1194396/

相关文章:

  • 如何用 AI 做竞品分析?产品经理效率提升指南
  • 紧急更新!OpenAI最新模型对文案策略的影响:3类失效Prompt预警及5套替代方案
  • CANN/asc-devkit VacantInQue函数
  • Malhar Angular Dashboard小部件自定义设置完全教程
  • BLHeli 电调固件完整配置指南:5分钟快速入门与性能优化技巧
  • 【VScode】无法建立ssh连接问题
  • 从Spotify到本地:3步打造永久音乐库的终极方案
  • CANN/asc-devkit GetPhyAddr函数文档
  • 肖特基二极管失效分析与工程防护方案
  • 5分钟掌握知乎数据采集:开源zhihu-spider完整解决方案
  • 合肥钻石回收就选奢二网,1500余家直营门店全国联网,合肥75店就近服务 - 生活时报
  • TestDisk PhotoRec:免费开源的数据恢复工具完整使用指南
  • 制造业质量提升神器——AI视觉检测系统
  • RSpotify错误处理与调试:解决常见API问题的完整解决方案
  • TTS语音合成常见错误与排错指南:从参数到响应的全链路排查
  • 为什么选择deepin-rpm-installer?openEuler系统RPM安装的最佳实践指南
  • SpringBoot穿越时光云养公益平台小程序开题报告
  • 【小程序计算机毕业设计案例】基于 SpringBoot+Android 的校园动态发布分享系统的设计与实现 学生校园社交互动系统(程序+文档+讲解+定制)
  • 幻兽帕鲁存档编辑终极指南:5分钟掌握游戏数据自由修改
  • 摄影器材借出去就石沉大海?我用飞算JavaAI做了个资产租赁管理台
  • cann/asc-devkit 元素对归约
  • 你还在手动截图代码?Cursor AI原生导出功能深度解锁(附VS Code无法实现的3大导出特权)
  • CANN/asc-devkit:GetTPipePtr函数
  • HAM测试指南:编写高质量单元测试与集成测试的最佳实践
  • Jido配置系统详解:默认配置与自定义配置最佳实践
  • 如何三步永久备份微信聊天记录?WeChatMsg免费工具完整指南
  • ChatGPT-Academic-Prompt高级应用:论文摘要优化与逻辑提升技巧
  • xfce桌面旋转说明:基于灵眸科技EASY-EAI-Nano-TB
  • 2026详细解读八字排盘App怎么选:看盘面依据、AI辅助和复盘边界
  • 知乎数据采集利器:zhihu-spider开源爬虫实战指南