OpUT
概述
OpUT为UT测试框架的基类,提供了测试用例定义及测试用例执行的接口,主要包含如下两个接口:
- add_case
- add_precision_case
OpUT测试类定义
- 函数原型
- 参数说明
- op_type:算子的类型。
- op_module_name:算子的module名称(即算子的实现文件名称和路径),例如:impl.add (文件路径为:impl/add.py)。默认值为None,可根据op_type自动生成,op_type到算子实现文件名称的转换规则可参见4,例如BiasAdd算子自动生成module名称"impl.bias_add"。
- op_func_name:算子的接口名称,算子实现文件中的算子接口名。默认值为None,可根据op_type自动生成,op_type到算子实现文件中接口名称的转换规则可参见4,例如Add算子,则需要在 impl/add.py 中存在add接口,接口定义如下所示:
@check_op_params(REQUIRED_INPUT, REQUIRED_INPUT, REQUIRED_OUTPUT, KERNEL_NAME) def add(input_x, input_y, output_z, kernel_name="add"):
add_case接口
- 函数原型
- 功能说明
- 参数说明
- support_soc:测试该用例是否支持对应的昇腾AI处理器,昇腾AI处理器的取值范围可从“compiler/data/platform_config”目录下查看,对应“*.ini”文件的名字即为可配置的昇腾AI处理器类型。support_soc支持的数据类型为str、tuple或者list,tuple或者list表示可以支持多个SoC。若配置为“all”或者“None”,表示支持所有的SoC。
- case:该参数为dict类型。
不带属性算子case示例:
{ "params": [ { "shape": (32, 64), "ori_shape": (32, 64), "format": "ND", "ori_format": (32, 64), "dtype": "float16" }, { "shape": (32, 64), "ori_shape": (32, 64), "format": "ND", "ori_format": (32, 64), "dtype": "float16" } ], "case_name": "test_add_case_1", "expect": "success" }
带属性算子case示例:# 以conv2d算子为例,详细算子实现请参见“样例工程”提供的conv2d算子实现文件。 # def get_op_support_info(inputs, weights, bias, offset_w, outputs, strides, pads, dilations,groups=1, data_format='NCHW', offset_x=0, kernel_name="conv2d") { "params": [ # inputs参数(tensor) {'shape': (1, 1, 16, 16, 16), "format": "NC1HWC0", 'ori_shape': (1, 16, 16, 16), 'ori_format': 'NCHW', 'dtype': 'float16', "param_type": "input", "value_range": [1.0, 2.0]}, # weights参数(tensor) {'shape': (1, 1, 16, 16), "format":"FRACTAL_Z", 'ori_shape': (16, 16, 1, 1), 'ori_format': 'NCHW', 'dtype': 'float16', "param_type": "input", "value_range": [1.0, 2.0]}, # bias参数 None, # offset_w参数 None, # outputs参数(tensor) {'shape':(1, 1, 16, 16, 16), 'ori_shape':(1, 16, 16, 16), "format": "NC1HWC0", 'ori_format': 'NCHW', "param_type": "output", 'dtype': 'float16'}, # strides参数 (1, 1, 1, 1), # pads参数 (0, 0, 0, 0), # dilations参数 (1, 1, 1, 1), # 可选groups参数 1, # 可选data_format参数 'NCHW', # 可选offset_x参数 0 "case_name": "test_conv2d_case_1", "expect": "success" }
该dict中key字段含义如表1所示:表1 key字段配置信息 参数
值
params
该字段在测试用例运行时透传给算子接口。该字段中的参数应与算子接口的参数顺序一致。
- 若输入的参数为tensor,可选择如下字段传递。
- shape:tensor的形状
- ori_shape:tensor的原始形状
- format:tensor的格式
- ori_format:tensor的原始格式
- param_type:tensor类型
- dtype: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
expect
期望结果。
默认为期望“success”,也可以是预期抛出的异常,例如RuntimeError。
- 若输入的参数为tensor,可选择如下字段传递。
add_precision_case接口
- 函数原型
- 功能说明
- 参数说明
- support_soc:测试该用例是否支持对应的昇腾AI处理器,昇腾AI处理器的取值范围可从“compiler/data/platform_config”目录下查看,对应“*.ini”文件的名字即为可配置的昇腾AI处理器类型。support_soc支持的数据类型为str、tuple或者list,tuple或者list表示可以支持多个SoC。若配置为“all”或者“None”,表示支持所有的SoC。
- case:该参数为dict类型,示例如下:
不带属性算子case示例:
{ "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) #可选字段 }
带属性算子case示例:# 以conv2d算子为例,详细算子实现请参见“样例工程”提供的conv2d算子实现文件。 # def get_op_support_info(inputs, weights, bias, offset_w, outputs, strides, pads, dilations,groups=1, data_format='NCHW', offset_x=0, kernel_name="conv2d") { "params": [ # inputs参数(tensor) {'shape': (1, 1, 16, 16, 16), "format": "NC1HWC0", 'ori_shape': (1, 16, 16, 16), 'ori_format': 'NCHW', 'dtype': 'float16', "param_type": "input", "value_range": [1.0, 2.0]}, # weights参数(tensor) {'shape': (1, 1, 16, 16), "format":"FRACTAL_Z", 'ori_shape': (16, 16, 1, 1), 'ori_format': 'NCHW', 'dtype': 'float16', "param_type": "input", "value_range": [1.0, 2.0]}, # bias参数 None, # offset_w参数 None, # outputs参数(tensor) {'shape':(1, 1, 16, 16, 16), 'ori_shape':(1, 16, 16, 16), "format": "NC1HWC0", 'ori_format': 'NCHW', "param_type": "output", 'dtype': 'float16'}, # strides参数 (1, 1, 1, 1), # pads参数 (0, 0, 0, 0), # dilations参数 (1, 1, 1, 1), # 可选groups参数 1, # 可选data_format参数 'NCHW', # 可选offset_x参数 0 "case_name": "test_conv2d_case_1", "calc_expect_func": np_conv2d #一个函数 "precision_standard": precision_info.PrecisionStandard(0.001, 0.001) #可选字段 }
该dict中key字段含义如表2下:表2 key字段配置信息 参数
值
params
该字段在测试用例运行时透传给算子接口。该字段中的参数应与算子接口的参数顺序一致。
- 若输入的参数为tensor,可选择如下字段传递。
- shape:tensor的形状
- ori_shape:tensor的原始形状
- format:tensor的格式
- ori_format:tensor的原始格式
- param_type:tensor类型
- dtype: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,可选择如下字段传递。
- 调用示例
示例1:
from op_test_frame.ut import OpUT # "ut_case" 为UT测试框架的关键字,不可修改 ut_case = OpUT("Add", "impl.add", "add") def np_add(x1, x2, y): y = (x1.get("value") + x2.get("value"), ) return y ut_case.add_precision_case(case={ "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": "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 }) if __name__ == '__main__': ut_case.run("Ascend910",None,"ca","/home/allan/Ascend/toolkit/tools/simulator")
ut_case.run:请参见run接口。
此样例未设置算子的输入数据值,测试框架将默认使用np.random.uniform(value_range, size=shape).astype(dtype)为每一个输入自动生成输入数据。
其中value_range使用默认值[0.1, 1.0],shape和dtype的取值为“params”中的每一个输入。value_range也可以通过参数指定,如下所示:
{ "shape": (32, 64), "ori_shape": (32, 64), "format": "ND", "ori_format": "ND", "dtype": "float16", "param_type": "input", "value_range": [2.0, 3.0] }
也可以指定输入的值,如下所示:
{ "shape": (32, 64), "ori_shape": (32, 64), "format": "ND", "ori_format": "ND", "dtype": "float16", "param_type": "input", "value": np.zeros((32, 64), np.float16) }
示例2:
自定义精度标准示例如下:
from op_test_frame.common import precision_info from op_test_frame.ut import OpUT ut_case = OpUT("Add") ut_case.add_precision_case(case={ "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": "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.1, 0.1) # 使用精度标准双十分之一,与期望数据进行比对 })
run接口
- 函数原型
OpUT.run(soc, case_name=None, simulator_mode=None, simulator_lib_path=None)
- 功能说明
- 参数说明
- soc:执行测试用例的昇腾AI处理器,昇腾AI处理器的取值范围可从Ascend-cann-toolkit安装目录/ascend-toolkit/latest/compiler/data/platform_config目录下查看,对应“*.ini”文件的名字即为可配置的昇腾AI处理器类型。support_soc支持的数据类型为str、tuple或者list,tuple或者list表示可以支持多个SoC。
- case_name:指定执行的case,配置为add_case接口及add_precision_case接口中的“case_name”。
- simulator_mode:默认为None,如果仅跑算子编译的测试用例,不需要指定。在添加了精度测试用例的时候,需要指定仿真的模式,使用"ca"或者"pv"。 如果指定"tm"将仅输出打点图,不进行精度比对。
- simulator_lib_path:仿真库所在的路径。
simulator_lib_path/ Ascendxxx/ lib/ libpv_model.so ... Ascendxxx/ lib/ libpv_model.so ...
使用MindStudio运行UT测试用例时,无需用户手工调用OpUT.run接口。