- 人工智能
- 深度学习
- 算子库
- CANN
- Ascend
【免费下载链接】asc-devkit
本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。
本文围绕 asc-devkit 算子调测(Tiling 调测)工具链中的context_ascendc::ContextBuilder::SetOpNameType接口展开,说明其函数原型、参数含义与返回值语义,并结合开源仓库源码剖析其底层调用链、默认值行为,以及与OpTilingRegistry按算子类型查找 Tiling 函数之间的关系。读完后,你可以独立编写可运行的 Tiling 调测代码,为手动构造的TilingContext正确设置算子身份,并将opType与注册表机制正确对应。
一、功能定位:Tiling 调测中的算子身份设置
在算子开发流程中,Tiling 函数(计算分块参数的 Host 端函数)通常运行在运行时上下文中,难以脱离推理框架单独调试。asc-devkit 为此提供了 Tiling 调测能力:ContextBuilder类提供一系列 Builder 风格 API,支持手动构造TilingContext来验证 Tiling 函数,以及手动构造KernelContext来验证TilingParse函数(见 Tiling 调测 ContextBuilder 简介)。
在手动构造TilingContext时,必须让上下文携带正确的"算子身份",即算子名字(opName)与算子类型(opType)。SetOpNameType正是承担这一职责的接口:
- 属于
OpInfo(算子信息)分组,与NodeIoNum、IrInstanceNum、AddInputTd、AddOutputTd、AddAttr等接口共同描述"这是一个什么算子、有多少输入输出、有哪些属性"; - 是
TilingContext构建链路的起始信息之一,通常与NodeIoNum、IrInstanceNum搭配使用; - 返回
ContextBuilder自身的引用,支持链式调用。
接口声明位于 ContextBuilder 公开头文件:
ContextBuilder &SetOpNameType(const std::string& opName, const std::string& opType);二、函数原型与参数说明
函数原型:
ContextBuilder &SetOpNameType(const std::string& opName, const std::string& opType)参数说明:
| 参数 | 输入/输出 | 说明 |
|---|---|---|
opName | 输入 | 算子名字。通常对应图中节点的实例名,例如自定义算子在图中的节点名,用于日志定位与调试标识 |
opType | 输入 | 算子类型。对应注册到算子实现空间(OpImplSpace)中的算子类型名,是 Tiling 函数注册与查找的关键键值 |
返回值说明:当前ContextBuilder的对象(即以引用形式返回调用者自身,支持链式调用)。
约束说明:文档未定义额外约束。从源码看,内部仅通过ASCENDC_ASSERT检查实现指针impl_非空,异常时会输出impl_ is nullptr!错误日志并提前返回。
三、源码剖析:SetOpNameType 的调用链与默认值行为
3.1 公开接口层:断言 + 委托 + 链式返回
SetOpNameType在 ContextBuilder 实现文件 中的实现非常简洁:
ContextBuilder& ContextBuilder::SetOpNameType(const std::string& opName, const std::string& opType) { ASCENDC_ASSERT(impl_ != nullptr, return *this, CXT_ASCENDC_LOGE("impl_ is nullptr!")); impl_->SetOpNameType(opName, opType); return *this; }这体现了ContextBuilder整体采用的 pimpl(指针到实现)+ 链式调用设计:公开类内部持有std::unique_ptr<ContextBuilderImpl> impl_(见 context_builder.h),每个 Setter 都先做非空断言,再委托给ContextBuilderImpl,最后return *this保证整条链式调用不断开。
3.2 实现层:写入 tilingCtxBuilder_ 的 OpName/OpType
ContextBuilderImpl 的实现 中,SetOpNameType被拆解为两个底层动作,写入gert::OpTilingContextBuilder:
void ContextBuilderImpl::SetOpNameType(const std::string& opName, const std::string& opType) { ASCENDC_ASSERT(tilingCtxBuilder_ != nullptr, return, CXT_ASCENDC_LOGE("tilingCtxBuilder_ is nullptr!")); tilingCtxBuilder_->OpName(opName.c_str()); tilingCtxBuilder_->OpType(opType.c_str()); }ContextBuilderImpl内部维护两个底层 Builder(见 context_builder_impl.h):
gert::OpKernelContextBuilder kernelCtxBuilder_:面向KernelContext(验证 TilingParse 函数);gert::OpTilingContextBuilder tilingCtxBuilder_:面向TilingContext(验证 Tiling 函数)。
因此可以确认:SetOpNameType只影响 TilingContext 构建链路。这与接口分组一致——它声明在头文件的 "OpInfo" 区域,而BuildTilingContext()才消费tilingCtxBuilder_累积的信息。
3.3 默认值行为:不调用 SetOpNameType 时会发生什么
从源码结构看,ContextBuilderImpl 构造函数 中已经为两个底层 Builder 预设了占位身份:
ContextBuilderImpl::ContextBuilderImpl() { kernelCtxBuilder_ = std::make_unique<gert::OpKernelContextBuilder>(); tilingCtxBuilder_ = std::make_unique<gert::OpTilingContextBuilder>(); tilingCtxBuilder_->OpName("default_name").OpType("default_type").IONum(1, 1); tilingCtxBuilder_->CompileInfo("default_compileinfo").PlatformInfo("default_platforminfo"); kernelCtxBuilder_->OpName("default_name").OpType("default_type").IONum(1, 1); }也就是说,即使不调用SetOpNameType,构造出的TilingContext也会携带opName = "default_name"、opType = "default_type"的占位身份。这意味着:
- 在纯调测场景(Tiling 函数不依赖算子身份做逻辑分支)下,
SetOpNameType可以省略; - 但如果你要复现真实算子行为(Tiling 函数或后续流程可能读取 opType 做实现选择),应显式传入真实的算子类型名,避免使用
default_type占位。
四、opType 的深层作用:与 OpTilingRegistry 的注册表查找机制联动
opType之所以是关键参数,是因为 Tiling 调测体系中还有一个配套类OpTilingRegistry,它负责按算子类型查找已注册的 Tiling 函数。查看 OpTilingRegistry::GetTilingFunc 的实现:
TilingFunc OpTilingRegistry::GetTilingFunc(const char* opType) const { auto registry = gert::DefaultOpImplSpaceRegistryV2::GetInstance().GetSpaceRegistry(); const gert::OpImplKernelRegistry::OpImplFunctionsV2* funcs; if (registry == nullptr) { CXT_ASCENDC_LOGD("failed to find implfuncs in 2.0 way, registery is null. op type is %s.", opType); return nullptr; } funcs = registry->GetOpImpl(opType); if (funcs == nullptr || funcs->tiling == nullptr || funcs->tiling_parse == nullptr) { return nullptr; } CXT_ASCENDC_LOGD("find implfuncs in 2.0 way, op type is %s.", opType); return funcs->tiling; }从源码结构看,GetTilingFunc(opType)以opType 字符串作为键,在DefaultOpImplSpaceRegistryV2注册表中查找对应的tiling函数指针(前提是tiling与tiling_parse均已注册)。这提示了SetOpNameType使用时的一个重要实践点:
- 传入的
opType应与算子在注册表/框架中登记算子类型保持一致,否则后续按 opType 取 Tiling 函数会得到nullptr,调试流程走不通; OpTilingRegistry还支持LoadTilingLibrary(tilingSoPath)动态加载算子 Tiling 库(内部通过dlopen+ 调用TbeLoadSoAndSaveToRegistry完成注册,见 实现代码),加载后同样以 opType 为键查询。
文档原文给出的调用示例中opType = "FlashAttentionScore"正是这种"真实算子类型名"的用法。
五、调用示例
5.1 文档标准示例(最小用法)
std::string opName = "tmpNode"; std::string opType = "FlashAttentionScore"; context_ascendc::ContextBuilder builder; (void)builder.SetOpNameType(opName, opType);说明:
opName = "tmpNode":模拟图中一个节点名(算子实例名);opType = "FlashAttentionScore":一个真实的算子类型名;- 返回值用
(void)显式丢弃,表达"我只要设置状态,不关心链式返回"的意图;由于接口返回自身引用,丢弃返回值不影响后续通过builder继续链式调用。
5.2 完整调测链路:SetOpNameType 在 TilingContext 构建中的位置
结合 ContextBuilder 简介文档 给出的标准用法,SetOpNameType是手动构造TilingContext链条中的基础一环:
// 构造TilingContext auto tilingContextHolder = context_ascendc::ContextBuilder() .SetOpNameType("MyOp", "MyOpType") // 指定算子名字与类型 .NodeIoNum(2, 1) // 2 个输入、1 个输出 .IrInstanceNum({1, 1}) // 各输入的 IR 实例数 .AddInputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, input_shape) .AddInputTd(1, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, weight_shape) .AddOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, output_shape) .AddAttr("activation", std::string("gelu")) .TilingData(param.get()) .Workspace(ws_size) .BuildTilingContext(); gert::TilingContext* tilingContext = tilingContextHolder->GetContext<gert::TilingContext>();ContextBuilder头文件中完整的 TilingContext 构建 API 面(SetOpNameType、NodeIoNum、IrInstanceNum、AddInputTd、AddOutputTd、AddAttr、CompileInfo、PlatformInfo、TilingData、Workspace、BuildTilingContext)均可在 context_builder.h 查阅。
5.3 仓库单元测试中的真实用法
仓库单测 test_tiling.cpp 大量使用了该接口,例如:
auto holder = context_ascendc::ContextBuilder() .NodeIoNum(1, 1) .IrInstanceNum({1}) .SetOpNameType("tmpName", "tmpType") .AddInputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, input_shape, file_path) .AddOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, output_shape) .TilingData(param.get()) .Workspace(ws_size) .BuildTilingContext();测试同时覆盖了多输入多属性场景(6 输入 1 输出、混合常量值/二进制文件输入、多种类型的AddAttr),验证了SetOpNameType与其余 OpInfo 接口在长链式调用中的稳定组合方式(见 TestTilingContextBuildWithBinFile 等用例)。需要说明的是,这些用例的调测目标是BuildTilingContext的容错行为(如常量数据文件缺失时返回空 holder),其中传入的"tmpName"/"tmpType"仅为占位身份。
六、使用要点与注意事项
- 返回自身引用,链式调用不断开:
SetOpNameType返回ContextBuilder&,可与NodeIoNum、AddInputTd等任意 Setter 自由组合;若单独调用,可像文档示例那样用(void)丢弃返回值。 - opName 与 opType 语义不同:opName 是节点实例名,偏标识与日志用途;opType 是算子类型,是注册表查找 Tiling 函数的键。构造真实调测环境时应优先保证 opType 与算子注册类型一致。
- 默认占位值兜底:不调用该接口时,上下文会携带
default_name/default_type占位身份(由ContextBuilderImpl构造函数预设),不会导致空值崩溃,但依赖 opType 的逻辑将无法正确路由。 - 仅作用于 TilingContext 链路:从源码看,
SetOpNameType写入的是tilingCtxBuilder_,由BuildTilingContext()消费;BuildKernelRunContext()走的是kernelCtxBuilder_(其 OpName/OpType 在构造时以默认值初始化),两条链路相互独立。 - 无额外前置约束:接口文档约束说明为"无",源码层仅有内部指针非空断言,属于可安全重复调用的 Setter,后一次调用会覆盖前一次设置的算子身份。
七、相关文档与源码索引
| 类型 | 路径 |
|---|---|
| 本文对应 API 文档 | SetOpNameType.md |
| ContextBuilder 调测简介 | intro.md |
| ContextBuilder 公开头文件 | context_builder.h |
| ContextBuilder 实现(含 OpTilingRegistry 查找逻辑) | context_builder.cpp |
| ContextBuilderImpl 声明 | context_builder_impl.h |
| ContextBuilderImpl 实现 | context_builder_impl.cpp |
| Tiling 调测单元测试 | test_tiling.cpp |
- 人工智能
- 深度学习
- 算子库
- CANN
- Ascend
【免费下载链接】asc-devkit
本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。
相关推荐
asc-devkit Tiling 上下文构建指南:用 ContextBuilder::BuildTilingContext 离线验证算子 Tiling 函数
asc devkit Tiling 上下文构建指南:用 ContextBuilder::BuildTilingContext 离线验证算子 Tiling 函数
人工智能深度学习算子库CANNAscendasc-devkit 中 ContextBuilder::IrInstanceNum 详解:为 Tiling 调测声明算子输入实例数
asc devkit 中 ContextBuilder::IrInstanceNum 详解:为 Tiling 调测声明算子输入实例数 在 asc devkit(
人工智能深度学习算子库CANNAscendasc-devkit 中 ContextBuilder 全解析:手动构造 TilingContext 与 KernelRunContext 验证算子 Tiling 函数
asc devkit 中 ContextBuilder 全解析:手动构造 TilingContext 与 KernelRunContext 验证算子 Tilin
人工智能深度学习算子库CANNAscend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考