CANN/ge UT开发指南

发布时间:2026/9/10 10:07:12

CANN/ge UT开发指南 UT用例开发指导【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge返回 DT用例开发总纲UT的测试范围是一个文件理论上一个UT应该对一个文件暴露的接口做测试并校验属于被测文件的行为。测试过程中UT用例应该认为其他文件的行为都是正确的、仅校验被测文件的行为。UT用例设计设计一个接口的测试点时注意关注以下点以下点为checklist如果不涉及或者认为不需要校验可以不设计对应用例错误值校验例如入参空指针超出规格范围边界值校验例如如果输入涉及Tensor考虑空Tensor场景如果被测模块涉及容器概念例如可以添加或管理多个element那么需要额外考虑如下因素插入动作发生在容器的开头、中间、结尾时删除动作发生在容器的开头、中间、结尾时如何校验做完整校验UT用例应该根据设计对所调用函数的返回值、出参做完整校验。如果所调用的函数产生了副作用那么应该对副作用做完整校验。所谓完整校验是指从外部可以观察到的、所有的变更点都应该校验。一种典型的错误是仅校验被测函数的返回值这种用例的作用极其有限应该避免。避免重复校验用例应该避免重复校验这意味着同一类校验尽量不要出现在多个不同的用例中。重复校验的主要问题在于加大了用例的维护难度在修改一个模块行为时导致多个用例失效。图类UT关注的校验点改图、构图类UT需要关注图的变化例如新增结点检查删除结点检查变更的连边检查变更的属性检查 以CEM的基础UT为例CEM(Constant Expression Motion)作用于执行图将执行图Main图中每次计算中不变的表达式移动到Init图中以达到加速Main图执行速度的作用。下面的用例中构造了一个注释中的Main Graph并期望通过一个Pass将Main图中的两个Const一个Foo1移动到Init图中/* * main graph: * * NetOutput * | * Foo2 * / \ * Foo1 data * / \ * const const */ TEST_F(ConstantExpressionsMotionUT, MoveToInit_Success_CeOnMain) { auto c1 ValueHolder::CreateConst(Hello, 5, true); auto c2 ValueHolder::CreateConst(World, 5, true); auto data ValueHolder::CreateFeed(0); auto foo1 ValueHolder::CreateSingleDataOutput(Foo, {c1, c2}); auto foo2 ValueHolder::CreateSingleDataOutput(Foo, {foo1, data}); auto main_frame ValueHolder::PopGraphFrame({foo2}, {}, NetOutput); auto root_frame ValueHolder::PopGraphFrame(); ASSERT_NE(root_frame, nullptr); ASSERT_NE(main_frame, nullptr); bool changed false; LoweringGlobalData global_data; ASSERT_EQ(ConstantExpressionMotion(global_data).Run(root_frame-GetExecuteGraph().get(), changed), ge::GRAPH_SUCCESS); ASSERT_TRUE(changed); EXPECT_EQ(ExeGraphSummaryChecker(main_frame-GetExecuteGraph().get()) .StrictDirectNodeTypes( std::mapstd::string, size_t{{Data, 1}, {Foo, 1}, {InnerData, 1}, {NetOutput, 1}}), success); EXPECT_EQ(ExeGraphSummaryChecker(init_frame_-GetExecuteGraph().get()) .StrictDirectNodeTypes(std::mapstd::string, size_t{{Const, 2}, {Foo, 1}, {InnerNetOutput, 1}}), success); EXPECT_EQ(de_init_frame_-GetExecuteGraph()-GetDirectNodesSize(), 0); ConnectFromInitToMain(foo1-GetFastNode(), 0, foo2-GetFastNode(), 0); changed false; ASSERT_EQ(ConstantExpressionMotion(global_data).Run(root_frame-GetExecuteGraph().get(), changed), ge::GRAPH_SUCCESS); ASSERT_FALSE(changed); }rt2 kernel类UT的校验点Kernel函数的范围RT2中的Kernel指为执行节点注册的一系列运行时函数的集合当前包括通过.RunFunc注册的Kernel执行函数即执行节点的计算逻辑通过.OutputsCreatorFunc注册的执行节点输出创建及初始化函数注意早期版本中的.OutputsInitializer及.OutputsCreator注册接口已废弃。通过.TracePrinter注册的节点自定义执行信息组装接口该接口在节点执行结束后调用返回该节点类型关注的context信息供框架进行节点执行trace信息打印。Kernel函数只为执行节点服务其函数签名不具备可读性通常应当设置为匿名函数。Kernel函数UT测试的策略对Kernel的UT测试是对某个执行节点的运行时相关函数的测试应当从执行节点发起而不是直接调Kernel函数。有些用例为了可以在UT中调用而将不可读的kernel函数签名符号导出有些本末倒置。框架保证调用Kernel相关函数时已正确申请输入输出any value内存Kernel函数编码时可以对输入输出的any value进行ASSERT防御性校验但是不推荐对其进行单独的UT测试即不要测试某个输入any value为空时的Kernel表现。这类用例当前代码里通常是一个叫输入异常的笼统名称预期执行失败。但是都是经不起推敲的比如为何测试只测试一个异常输入场景而不测试不同异常组合下的返回名言部分的证明等于0说明了这种验证的意义。Kernel函数的测试点说明你可能需要关注测试点4中对TracePrinter函数的相关说明测试点1根据执行节点类型能正确查询到注册的Kernel系列函数auto funcs registry.FindKernelFuncs(YourTestingOpType); ASSERT_NE(funcs, nullptr); ASSERT_NE(funcs-outputs_creator, nullptr); // 根据是否注册决定是否校验 ASSERT_EQ(funcs-outputs_creator(nullptr, context), ge::GRAPH_SUCCESS); // 根据是否注册决定是否校验 ASSERT_NE(context-GetOutputPointerShape(0), nullptr); // 根据是否注册决定是否校验测试点2对执行节点的OutputsCreatorFunc函数测试如果执行节点注册了OutputsCreatorFunc则对OutputsCreatorFunc函数进行UT测试通常只需要测试OutputsCreatorFunc的返回值正确即可。ASSERT_NE(funcs-outputs_creator, nullptr); ASSERT_EQ(funcs-outputs_creator(nullptr, context), ge::GRAPH_SUCCESS);我们建议只写一个校验OutputsCreatorFunc正常执行的用例出于以下考虑接口返回正确代表完成了全部的创建和初始化动作对创建的内容的校验是冗余的对创建内容的校验是不充分且不可信的因为无法从any value对象存储的指针上校验类型测试点3对执行节点的Kernel执行函数测试这部分需要针对Kernel执行函数的实现设计合理的测试用例。 但是需要明确用例的边界在调用Kernel执行函数前需要保证已经正确创建了KernelContext输入输出any value内存并调用OutputsCreatorFunc注册函数如果有的话这两部分是测试的前置条件。TEST_F(BuildTensorUT, SplitTensor_Host) { auto tensor_holder TensorFaker().Shape({10, 20}).Format(ge::FORMAT_ND).Placement(kOnHost).Build(); auto context_holder KernelRunContextFaker() .KernelIONum(2, static_castsize_t(kernel::SplitTensorOutputs::kNum)) .NodeIoNum(1, 1) .Inputs({tensor_holder.GetTensor(), gert_allocator}) .Build(); auto run_context context_holder.GetContextKernelContext(); auto funcs registry.FindKernelFuncs(kernel::kSplitDataTensor); ASSERT_NE(funcs, nullptr); ASSERT_EQ(funcs-outputs_creator(FastNodeFaker().Build(), run_context), ge::GRAPH_SUCCESS); ASSERT_EQ(funcs-run_func(run_context), ge::GRAPH_SUCCESS); // 调用执行函数 // check tensor data auto tensor_data_chain run_context-GetOutput(static_castsize_t(kernel::SplitTensorOutputs::kTensorData)); // 获取输出并校验结果 ASSERT_NE(tensor_data_chain, nullptr); EXPECT_TRUE(tensor_data_chain-HasDeleter()); auto tensor_data tensor_data_chain-GetPointerGertTensorData(); ASSERT_NE(tensor_data, nullptr); EXPECT_EQ(tensor_data-GetAddr(), tensor_holder.GetTensor()-GetAddr()); // check shape auto shape run_context-GetOutputPointerStorageShape(static_castsize_t(kernel::SplitTensorOutputs::kShape)); ASSERT_NE(shape, nullptr); EXPECT_EQ(*shape, tensor_holder.GetTensor()-GetShape()); context_holder.FreeAll(); }注意如果你正在写一个期望Kernel执行函数失败的用例请务必慎重这是否是一个真实存在的运行时输入场景如果不是很容易陷入部分证明的泥潭 -- 为何不测试全部的异常输入组合。即使你罗列了全部的异常组合也会陷入用例数量爆炸的另一个泥潭。我们可以在Kernel执行函数内部进行一些BUG场景的ASSERT防御性校验但是不应该对其进行单独的UT测试。测试点4对TracePrinter函数进行测试TracePrinter函数的功能是从context中收集所需的执行信息在调用时序上发生在Kernel执行函数调用后。需要特别注意的是当前执行逻辑下即使Kernel执行函数返回错误仍会调用该函数因此函数实现时对于Kernel输出的处理需要格外慎重必须与Kernel执行函数严格匹配。在目前调用时机未修改且无法获知执行结果的情况下需要开发者谨慎地实现TracePrinter函数确保在Kernel执行函数异常退出时不会发生运行时错误即使这很难实现。将来大概率会修改该函数的调用时机或调用时传入执行结果信息。基于当前的调用时机我们只建议对TracePrinter进行两部分的测试测试用例1测试Kernel执行函数正常执行后的返回信息registry.FindKernelFuncs(LaunchKernelWithFlag)-run_func(context.WithFlag()) auto ret registry.FindKernelFuncs(LaunchKernelWithFlag)-trace_printer(context.WithFlag()); EXPECT_FALSE(ret.empty());注意该测试是不充分的假定了处理执行函数错误时不对输出进行任何修改这通常是不成立的。测试用例2模拟测试Kernel执行函数异常时的返回信息待定构造 -run_func() 失败的场景然后调用 -trace_printer 方法【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/10 10:07:12

CANN/GE算子形状推断函数实现

IMPLEMT_INFERFUNC 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、TensorF…

2026/9/10 10:02:10

MTProxy配置参数详解:从端口设置到worker数量优化

MTProxy配置参数详解:从端口设置到worker数量优化 MTProxy是一款高效的代理工具,本文将详细解析其核心配置参数,帮助新手用户快速掌握从端口设置到worker数量优化的全过程,轻松搭建稳定可靠的代理服务。 一、基础参数解析 1.1 …

2026/9/10 11:02:21

WSABuilds v2407.40000.4.0_v2:WSA 安装失败修复与升级指南

WSABuilds v2407.40000.4.0_v2:WSA 安装失败修复与升级指南 【免费下载链接】WSABuilds Run Windows Subsystem For Android on your Windows 10 and Windows 11 PC using prebuilt binaries with Google Play Store (MindTheGapps) and/or Magisk or KernelSU (roo…

2026/9/10 11:02:21

道桥安全改革试点方案的政策依据与实施路径

近年来,我国公路桥涵养护领域的标准体系迎来密集更新:从《公路桥涵养护规范》的全面修订,到《公路养护技术标准》作为养护板块龙头标准的落地,再到桥梁结构监测技术规范的迭代升级,一系列制度安排正在重塑道桥安全治理…

2026/9/9 13:11:35

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/8 7:15:15

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 0:00:55

目录对比去重实战:用哈希算法精准清理重复文件

我电脑里现在还有一块换了三次机的“数据墓地”硬盘,里面存着2016年以前所有旧笔记本的完整备份。平时不觉得有什么,直到前阵子想把它整理归档,发现同一个安装包、同一批照片、同一份论文草稿,在几个不同的备份目录里反复出现。更…

2026/9/10 0:00:55

Leaflet离线地图完整Demo合集:内网部署与坐标纠偏实战

简介:这是一份面向Web GIS开发者的LeafLet离线地图示例合集,帮助开发者快速掌握离线地图从搭建到交互的完整流程。压缩包共723个文件,大小14.06MB,以319个js脚本、175个html页面和29个css样式文件为主体,配合png/svg图…

2026/9/10 0:00:55

MATLAB读取Rinex 3.02观测文件:多系统GNSS数据解析实战

简介:基于MATLAB开发的Rinex3.02版观测文件(o文件)读取代码包,面向卫星定位导航方向的学习者与研究人员,用于解决新版观测文件的数据解析、历元提取与时间转换问题。压缩包共4个文件,包含两个m脚本、一个19…

2026/9/7 16:23:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/7 22:46:00

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/9 10:21:54

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码