news 2026/10/16 5:34:45

asc-devkit Tiling 调测工具详解:ContextBuilder 构造函数的 Builder 模式与默认成员初始化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
asc-devkit Tiling 调测工具详解:ContextBuilder 构造函数的 Builder 模式与默认成员初始化
  • 人工智能
  • 深度学习
  • 算子库
  • CANN
  • Ascend

【免费下载链接】asc-devkit

本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。

项目地址:https://gitcode.com/cann/asc-devkit
点击查看免费下载

在 asc-devkit 的 Tiling 调测(Tiling tuning)工具中,context_ascendc::ContextBuilder是手动构造TilingContext与KernelContext的核心入口类,用于脱离图引擎环境验证 Tiling 函数与 TilingParse 函数。本文以 ContextBuilder 构造函数 官方文档为主体,结合仓库头文件、实现源码与单元测试,剖析该无参构造函数“初始化数据成员”这一行为的具体实现:它如何通过 pimpl(pointer to implementation)模式持有内部实现,并为后续 Builder 链式调用建立哪些默认状态,以及非拷贝、禁移动的设计约束对使用者意味着什么。

ContextBuilder 在 Tiling 调测中的定位

Tiling 调测工具属于 asc-devkit 的 Utils-API 能力之一,其文档索引见 Tiling_tuning,包含OpTilingRegistry与ContextBuilder两组接口。其中 ContextBuilder 简介文档说明:

ContextBuilder 类提供一系列的 API 接口,支持手动构造 TilingContext 类来验证 Tiling 函数以及 KernelContext 类用于 TilingParse 函数的验证。

也就是说,开发者在独立调测一个算子的 Tiling 函数(如MyAddTiling::Init)或TilingParse时,可以不必依赖完整的模型推理环境,而是通过ContextBuilder手工拼出与运行时等价的数据结构。ContextBuilder的全部成员声明位于 context_builder.h:

class ContextBuilder { public: ContextBuilder(); ~ContextBuilder(); ContextBuilder(ContextBuilder &&kernelRunContextBuilder) = delete; ContextBuilder &operator=(ContextBuilder &&kernelRunContextBuilder) = delete; // kernel context builder ContextBuilder &Inputs(std::vector<void *> inputs); ContextBuilder &Outputs(std::vector<void *> outputs); std::shared_ptr<KernelRunContextHolder> BuildKernelRunContext(); // OpInfo ContextBuilder &NodeIoNum(size_t inputNum, size_t outputNum); ContextBuilder &SetOpNameType(const std::string& opName, const std::string& opType); // ... AddInputTd / AddOutputTd / AddAttr / CompileInfo / PlatformInfo / // AddPlatformInfo / TilingData / Workspace 等设置接口,均返回 ContextBuilder& std::shared_ptr<KernelRunContextHolder> BuildTilingContext(); private: std::unique_ptr<ContextBuilderImpl> impl_; };

从源码结构看,该类是典型的Builder 模式 + pimpl 惯用法:对外暴露链式设置接口(每个 setter 返回ContextBuilder&),内部仅持有一个std::unique_ptr<ContextBuilderImpl> impl_,将所有状态转移到私有实现类 ContextBuilderImpl。构造函数正是建立这一内部状态的第一步。

函数原型、参数与约束

官方文档对ContextBuilder构造函数的定义如下(完整继承自 ContextBuilder_constructor.md):

  • 功能说明:创建 ContextBuilder 对象时,初始化数据成员。
  • 函数原型:
ContextBuilder()
  • 参数说明:无。
  • 约束说明:无。

这是一个无参默认构造函数,且类声明未提供任何其他构造方式(没有带参构造,也没有工厂函数),因此每一个可用的ContextBuilder对象都必然经由该构造函数创建。下面结合实现看“初始化数据成员”究竟做了什么。

构造函数做了什么:从 ContextBuilder 到 ContextBuilderImpl

ContextBuilder构造函数的实现非常简短,位于 context_builder.cpp:

ContextBuilder::ContextBuilder() { impl_.reset(new ContextBuilderImpl); } ContextBuilder::~ContextBuilder() = default;

它做且仅做一件事:为impl_分配一个ContextBuilderImpl实例。真正的“数据成员初始化”发生在ContextBuilderImpl的构造函数中,见 context_builder_impl.cpp:

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); }

可以归纳出,一次ContextBuilder()构造会在内存中建立以下状态:

初始化项所属实现类初值 / 说明
impl_ContextBuilder指向新建的ContextBuilderImpl(pimpl 指针)
kernelCtxBuilder_ContextBuilderImpl新建gert::OpKernelContextBuilder,用于BuildKernelRunContext()
tilingCtxBuilder_ContextBuilderImpl新建gert::OpTilingContextBuilder,用于BuildTilingContext()
OpName / OpType两个底层 Builder默认值"default_name"/"default_type",可被SetOpNameType覆盖
输入/输出数量(IONum)两个底层 Builder默认(1, 1),可被NodeIoNum/IrInstanceNum覆盖
CompileInfo / PlatformInfotilingCtxBuilder_占位字符串"default_compileinfo"/"default_platforminfo",可被CompileInfo/PlatformInfo/AddPlatformInfo覆盖
errFlag_ContextBuilderImplfalse(成员声明处初始化),后续AddInputTd等步骤出错时置位
inputNum_/outputNum_ContextBuilderImpl0(成员声明处初始化)

从源码结构看,这一设计的意义在于:构造函数保证对象诞生时即处于“可直接链式配置、或直接 Build 出最简默认 Context”的合法状态,所有 setter 都是对默认值的逐步细化。ContextBuilderImpl中另有dependTensorsData_/dependOutputTensorsData_两个std::unordered_map<int32_t, std::unique_ptr<uint8_t[]>>成员(见 context_builder_impl.h),用于暂存AddInputTd/AddOutputTd创建的张量数据,默认构造时为空容器,按需填充。

对象语义:不可拷贝、不可移动

context_builder.h 中还显式删除了两个移动操作:

ContextBuilder(ContextBuilder &&kernelRunContextBuilder) = delete; ContextBuilder &operator=(ContextBuilder &&kernelRunContextBuilder) = delete;

同时由于impl_是std::unique_ptr,隐式拷贝构造/拷贝赋值天然被删除。也就是说:ContextBuilder是一个非可移动、非可拷贝的对象,只能通过默认构造创建、以引用方式在链式调用中传递(这正是全部 setter 返回ContextBuilder&的原因)。实际使用时应让链式表达式直接绑定到同一个临时对象上,例如context_ascendc::ContextBuilder().SetOpNameType(...)...BuildTilingContext(),或将其作为局部变量声明后复用,而不能“存一份副本”或“移动进容器”。

典型使用方式:构造函数作为链式调用的起点

官方简介文档给出的两种构造范式(见 intro.md)都以context_ascendc::ContextBuilder()的临时对象构造作为链条起点:

// 构造 KernelContext(验证 TilingParse) auto kernelContextHolder = context_ascendc::ContextBuilder() .Inputs(...) .Outputs(...) .BuildKernelRunContext(); gert::KernelContext* tilingParseContext = kernelContextHolder->GetContext<gert::KernelContext>(); // 构造 TilingContext(验证 Tiling 函数) auto tilingContextHolder = context_ascendc::ContextBuilder() .SetOpNameType(..., ...) .NodeIoNum(...) .IrInstanceNum(...) .AddInputTd(...) .AddOutputTd(...) .AddAttr(...) .BuildTilingContext(); gert::TilingContext* tilingContext = tilingContextHolder->GetContext<gert::TilingContext>();

这里的...参数可以参照仓库中的真实单测 test_tiling.cpp 补全,该用例完整走了一遍“构造 → 配置 → BuildTilingContext”的链路:

auto holder = context_ascendc::ContextBuilder() .NodeIoNum(1, 1) // 1 个输入、1 个输出 .IrInstanceNum({1}) // 每个输入的 IR 实例数 .SetOpNameType("tmpName", "tmpType") // 算子名 / 算子类型 .AddInputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, input_shape, file_path) // 输入 0:shape + bin 数据文件 .AddOutputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND, output_shape) .TilingData(param.get()) // 由 gert::TilingData::CreateCap 分配 .Workspace(ws_size) // 由 gert::ContinuousVector 提供 .BuildTilingContext();

两个值得注意的实现细节(来自 context_builder_impl.cpp):

  1. 出错即“静默失败”的 errFlag 机制:AddInputTd/AddOutputTd在张量尺寸非法、bin 文件读取失败、内存分配失败等场景下不会抛异常,而是将errFlag_置true并记录日志;随后BuildTilingContext()检测到errFlag_时打印"Build Context Error!"并返回nullptr(见 BuildTilingContext 实现)。因此单测中对失败路径的断言是EXPECT_EQ(holder, nullptr)——判断 Build 是否成功,必须检查返回值是否为空指针。
  2. 构造函数与 Build 的配对关系:ContextBuilderImpl构造时创建的kernelCtxBuilder_与tilingCtxBuilder_分别服务于两条 Build 路径。BuildKernelRunContext()只依赖Inputs/Outputs设置;BuildTilingContext()则消费NodeIoNum/IrInstanceNum/AddInputTd/AddOutputTd/AddAttr/CompileInfo/PlatformInfo/TilingData/Workspace的累计状态,最终通过tilingCtxBuilder_->Build()得到gert::ContextHolder<gert::TilingContext>,并包装为std::shared_ptr<KernelRunContextHolder>返回,由 holder 管理 Context 及其张量数据的生命周期。

小结

  • ContextBuilder()是无参默认构造,无参数、无额外约束(相对文档所述),是ContextBuilder唯一的对象创建入口。
  • 其“初始化数据成员”的实质是:分配 pimpl 指针impl_,并在ContextBuilderImpl内建立gert::OpKernelContextBuilder与gert::OpTilingContextBuilder两个底层构建器,同时写入default_name/default_type/IONum(1,1)等可覆盖的默认值(context_builder_impl.cpp#L58-L66)。
  • 对象不可拷贝、不可移动,只能就地声明并以返回值引用进行链式配置;Build*系列接口以空指针表示失败,调用方需显式判空。
  • 深入开发时,可结合 Tiling_tuning 文档目录 中ContextBuilder各 setter 页面(如 AddInputTd、BuildTilingContext)与 OpTilingRegistry 一起使用,并在 tests/api/utils/tiling/test_tiling.cpp 中参考完整调用链与错误路径的验证方式。
  • 人工智能
  • 深度学习
  • 算子库
  • CANN
  • Ascend

【免费下载链接】asc-devkit

本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C++标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。

项目地址:https://gitcode.com/cann/asc-devkit
点击查看免费下载
上一篇:ant-design Select 语义化定制完全指南:用 classNames 与 styles 精准控制每一层 DOM
下一篇:Appium Inspector与云测试平台集成:BrowserStack/Sauce Labs配置教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 5:33:16

顶层设计先行:企业如何建设数据系统的战略规划全解析

IDC数据显示&#xff0c;2026年中国数据治理平台市场规模突破860亿元&#xff0c;年复合增长率达29.7%&#xff0c;其中大型企业贡献超过65%的采购份额。然而&#xff0c;Gartner在2026年的研究中指出&#xff0c;80%的数据与分析治理举措可能因缺乏业务驱动力而失效&#xff0…

作者头像 李华
网站建设 2026/10/16 5:33:11

分布式定时任务系列5:XXL-job中blockingQueue的应用

传送门 分布式定时任务系列1&#xff1a;XXL-job安装 分布式定时任务系列2&#xff1a;XXL-job使用 分布式定时任务系列3&#xff1a;任务执行引擎设计 分布式定时任务系列4&#xff1a;任务执行引擎设计续 分布式定时任务系列6&#xff1a;XXL-job触发日志过大引发的CPU告…

作者头像 李华
网站建设 2026/10/16 5:32:27

MicroPython驱动L298N电机模块:供电、PWM调速与多电机协同实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 5:32:26

三次样条插值二类边界条件:从三弯矩方程到Matlab完整实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 5:31:04

电商服务增长实战:从低成本服务细节到复购率提升

这两年我接触到的电商商家&#xff0c;几乎都在聊同一件事&#xff1a;流量越来越贵&#xff0c;价格越杀越狠&#xff0c;利润薄得像纸。但就在这种环境里&#xff0c;有一批商家反而活得很好——他们没去卷低价&#xff0c;没去砸付费推广&#xff0c;而是把力气花在了“服务…

作者头像 李华
网站建设 2026/10/16 5:30:58

Java面试必考Elasticsearch:从倒排索引到分布式调优全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华