UT测试
生成UT测试用例定义文件
编写算子实现代码的UT Python测试用例,计算出算子执行结果,并取回结果和预期结果进行比较,来测试算子逻辑的正确性。
# 导入UT测试类,可根据算子类型选择使用哪个测试类 from op_test_frame.ut.ascendc_op_ut import AscendcOpUt from op_test_frame.common import precision_info # 针对Atlas 训练系列产品、Atlas 推理系列产品,配置样例如下: platforms = ["Ascendxxxyy"] //需按照实际使用的型号配置 # 实例化UT测试用例,ut_case为UT测试框架关键字,不可修改;add_custom为算子的Type ut_case = AscendcOpUt('add_custom') # 返回期望数据 def calc_expect_func_infer(x, y, z): z = x.get("value") + y.get("value") return [z, ] # 添加测试用例,input和output为算子的输入和输出描述,case_name为测试用例的名称,请根据实际进行编辑 ut_case.add_precision_case(platforms, {'params': [ {'dtype': 'float16', 'format': 'ND', 'ori_format': 'ND', 'ori_shape': [8, 2048], 'param_type': 'input', 'shape': [8, 2048], 'distribution': 'normal', 'value_range': [-10, 10]}, {'dtype': 'float16', 'format': 'ND', 'ori_format': 'ND', 'ori_shape': [8, 2048], 'param_type': 'input', 'shape': [8, 2048], 'distribution': 'normal', 'value_range': [-10, 10]}, {'dtype': 'float16', 'format': 'ND', 'ori_format': 'ND', 'ori_shape': [8, 2048], 'param_type': 'output', 'shape': [8, 2048]}], "case_name": 'add_custom_1', "calc_expect_func": calc_expect_func_infer, "precision_standard": precision_info.PrecisionStandard(0.005, 0.005) }) # 若定义多个用例,定义多个ut_case.add_precision_case函数 ut_case.add_precision_case(platforms, {'params': [ {'dtype': 'float16', 'format': 'ND', 'ori_format': 'ND', 'ori_shape': [8, 2048], 'param_type': 'input', 'shape': [8, 2048], 'distribution': 'normal', 'value_range': [-10, 10]}, {'dtype': 'float16', 'format': 'ND', 'ori_format': 'ND', 'ori_shape': [8, 2048], 'param_type': 'input', 'shape': [8, 2048], 'distribution': 'normal', 'value_range': [-10, 10]}, {'dtype': 'float16', 'format': 'ND', 'ori_format': 'ND', 'ori_shape': [8, 2048], 'param_type': 'output', 'shape': [8, 2048]}], "case_name": 'add_custom_2', "calc_expect_func": calc_expect_func_infer, "precision_standard": precision_info.PrecisionStandard(0.005, 0.005) })
- 首先导入UT测试类,用户可根据算子类型自行选择使用哪个UT测试类。
- 实例化测试用例,AscendcOpUt的使用方法可参见AscendcOpUt测试类定义。
- 如有调用add_precision_case接口,可参考add_precision_case接口在test_add_custom_impl.py文件进行“calc_expect_func”参数配置。
- 添加测试用例。
测试用例“params”中字段和字段取值范围需根据算子实现文件入口参数确定。输入的“ori_shape”和“ori_format”字段为可选字段,但若使用参数校验修饰器检验参数,“ori_shape”和“ori_format”字段必选。
若要与期望数据进行结果的比对,请使用add_precision_case接口。
- “ori_format”和“ori_shape”为可选字段,不带此字段时,默认Tensor的实现format和shape与原始format和shape一致。
- “format”、“dtype”和“shape”的数量需保持一致,配置的“shape”需要和“format”相匹配。
- “output”中参数取值的个数都要与“input”一致,否则测试用例生成会失败。
例如:“input”的format支持的类型个数2,则“output”的format支持的类型个数也需要为2。
- 一个算子所有“input”中参数取值的个数都要一致,否则测试用例生成会失败。
所有“input”中的dtype、shape、distribution和value_range的取值个数也需要保持一致。
add_precision_case接口
- 函数原型
- 功能说明
- 参数说明
- support_soc:测试该用例中昇腾AI处理器的取值范围可从“$HOME/Ascend/ascend-toolkit/latest/compiler/data/platform_config”目录下查看,对应“*.ini”文件的名字即为可配置的昇腾AI处理器类型,请根据实际版本进行选择。support_soc支持的数据类型为str、tuple或者list,tuple或者list表示可以支持多个SoC。若配置为“all”或者“None”,表示支持所有的SoC。
- case:该参数为dict类型,示例如下:
{ "params": [ { "shape": (32, 64), "ori_shape": (32, 64), "format": "ND", "ori_format": "ND", "dtype": "float16", "param_type": "input" }, { "shape": (32, 64), "ori_shape": (32, 64), "format": "ND", "ori_format": "ND", "dtype": "float16", "param_type": "output" } ], "case_name": "test_add_case_1", "calc_expect_func": np_add #一个函数 "precision_standard": precision_info.PrecisionStandard(0.001, 0.001) #可选字段 }
该dict中key字段含义如表1所示:表1 key字段配置信息 参数
值
params
该字段在测试用例运行时透传给算子接口。该字段中的参数应与算子接口的参数顺序一致。
- 若输入的参数为tensor,可选择如下字段传递。
- shape:tensor的形状
- ori_shape:tensor的原始形状
- format:tensor的格式
- ori_format:tensor的原始格式
- param_type:tensor类型
- dtype:tensor的数据类型
- distribution:tensor的分布方式
- value_range:tensor取值范围,默认值为[0.1, 1.0]
- 若输入的参数为非tensor,请传递实际参数值。
- 若输入的参数为空,请传递None。
case_name
测试用例的名称,可选参数。若不设置,测试框架会自动生成用例名称,生成规则如下:
test_{op_type}_auto_case_name_{case_count}
例如: test_Add_auto_case_name_1
calc_expect_func
期望结果生成函数。
precision_standard
自定义精度标准,取值为:(rtol, atol, Max_atol)。
- rtol:相对容忍率
- atol:绝对容忍率
- Max_atol:(可选)最大容忍率
说明:若不配置此字段,按照如下默认精度与期望数据进行比对:- 数据类型为float16时:双千分之一,(0.001, 0.001, 0.1),即每个数据之间的误差不超过千分之一,误差超过千分之一的数据总和不超过总数据数的千分之一。
- 数据类型为float32时:双万分之一,(0.0001, 0.0001, 0.01),即每个数据之间的误差不超过万分之一,误差超过万分之一的数据总和不超过总数据数的万分之一。
- 数据类型为int8或uint8时:(0.001, 1, 1),即每个数据之间的误差不超过一,误差超过一的数据总和不超过总数据数的千分之一。
- 若输入的参数为tensor,可选择如下字段传递。
执行UT测试用例
- 请用户完成输入文件的准备工作。
- 获取待测试算子的测试用例定义文件(test_*_impl.py),请参见生成UT测试用例定义文件。
- 获取算子实现文件(*.cpp文件),具体可参考Kernel侧算子实现。
- 进入op_ut_run工具所在目录执行如下命令,参数说明请参见表2。${INSTALL_DIR}/python/site-packages/bin/op_ut_run --case_files {test case file} --case_name {case name } --data_path {test case data file} --process_num {process num} --simulator_lib_path {simulator library path} --simulator_data_path {simulator dump data files} --simulator_mode {simulator model} --ascendc_op_path {*.cpp file } --block_dim {block_dim} --soc_version {soc_version}
表2 参数说明 参数名称
参数描述
是否必选
--case_files
测试用例定义文件(test_*_impl.py文件)。
是
--case_name
测试用例文件中的用例名称。
- 配置为需要执行的case的名字,若需要同时运行多个case,多个case之间使用逗号分隔。
- 若配置为“all”,或者不配置此参数,代表执行所有case。
否
--data_path
保存运行过程中生成的测试用例数据.bin文件所在路径,可配置为绝对路径或者相对路径,并且工具执行用户具有可读写权限。
默认值:“./data”。
否
--process_num
UT测试的进程数目。
默认值:“1”。
否
--simulator_lib_path
配置仿真环境运行依赖,指定配置为$HOME/Ascend/ascend-toolkit/latest/toolkit/tools/simulator目录。
是
--simulator_data_path
仿真环境dump数据存放目录,可配置为绝对路径或者相对路径,并且工具执行用户具有可读写权限。
默认值:“./model”。
否
--simulator_mode
运行测试用例的仿真环境,可支持配置为ca或pv。
- pv:即PVModel,为功能仿真环境(Simulator Function)。
- ca:即CAModel,为性能仿真环境(Simulator Performance)。
是
--ascendc_op_path
算子实现文件(.cpp文件)路径,可配置为绝对路径或者相对路径
说明:仅支持配置一个需要运行的算子实现文件。
是
--block_dim
算子核函数运行所需核数。
默认值:“1”。
否
--soc_version
配置昇腾AI处理器的类型,请根据实际版本进行选择。
说明:- 在安装昇腾AI处理器的服务器执行npu-smi info命令进行查询,获取Chip Name信息。实际配置值为AscendChip Name,例如Chip Name取值为xxxyy,实际配置值为Ascendxxxyy。
是
示例:
进入op_ut_run工具所在目录,执行如下命令:./op_ut_run --case_files=xx/test_add_custom_impl.py --data_path=./data --simulator_data_path=./model --simulator_lib_path=/usr/local/Ascend/ascend-toolkit/latest/toolkit/tools/simulator --simulator_mode=ca --soc_version=Ascendxxxyy --case_name=add_custom_1 --ascendc_op_path=xx/add_custom.cpp --block_dim=8
- 执行完成后,屏显信息为此次用例运行的情况,如图1所示。
- 查看生成的dump数据,目录结构如下所示:
├──{model} //默认目录或自定义数据存放目录 │ └── ca //simulator_mode配置为ca时生成此目录 │ └── add_custom //根据op_type生成 │ └── add_custom_pre_static_test_Add_auto_case_name_1 // 以{op_type}_pre_static_test_{case_name}命名的目录下存放的dump数据 │ ├── core0_xx.dump │ ├── core0_xx_xx.dump │ ├── core1_xx.dump │ ├── core1_xx_xx.dump │ ├── core10_xx.dump │ ├── core10_xx_xx.dump │ └── pv //simulator_mode配置为pv时生成此目录 │ └── add_custom ///根据op_type生成 │ └──add_custom_pre_static_test_Add_auto_case_name_1 // 以{op_type}_pre_static_test_{case_name}命名的目录下存放的dump数据 │ ├── core0_xx.dump │ ├── core0_xx_xx.dump │ ├── core1_xx.dump │ ├── core1_xx_xx.dump │ ├── core10_xx.dump │ ├── core10_xx_xx.dump