文档
注册

UT测试

简介

MindStudio提供了基于gtest框架的新的UT测试方案,简化了开发者开发UT测试用例的复杂度。

UT(Unit Test:单元测试)是开发人员进行单算子运行验证的手段之一,主要目的是:

  • 测试算子代码的正确性,验证输入输出结果与设计的一致性。
  • UT侧重于保证算子程序能够正常运行,选取的场景组合应能覆盖算子代码的所有分支(一般情况下覆盖率要达到100%),从而降低不同场景下算子代码的编译失败率。

测试类的详细定义可参见Ascend-cann-toolkit安装目录/ascend-toolkit/latest/python/site-packages/op_test_frame/ut/op_ut.py文件。

前提条件

需完成自定义算子的开发,包括算子实现代码和算子原型定义,详情可参见算子代码实现算子原型定义

  • CentOS7.8 arm容器暂不支持算子实现代码的UT测试功能。
  • Windows版本的MindStudio UT测试的算子工程目录中不要出现空格。

生成UT测试用例文件

  1. 创建UT测试用例。
    1. 创建UT测试用例,有以下两种方式:

      右键单击算子工程根目录,选择New Cases > TBE UT Case

      若已经存在了算子的UT测试用例,可以右键单击“testcases”目录或“testcases > ut”目录,选择New Cases > TBE UT Case,创建UT测试用例。

    2. 在弹出的算子选择界面,选择需要创建UT测试用例的算子,单击“OK”,如下图所示。

      若已存在此算子的UT测试用例,系统会提示“testcases/ut/ops_test/xx already exists. Do you want to overwrite?”。

      可以选择“Overwrite”覆盖当前测试用例或者“Cancel”取消覆盖。

      创建完成后,会在算子工程根目录下生成testcases文件夹,目录结构如下所示:

      ├── MyOperator            //工程根目录  
      │   ├──  testcases                            
      │   │   ├── libs                  // gtest框架,为第三方依赖,用户无需关注
      │   │   ├──  ut                              
      │   │   │   ├── ops_test
      │   │   │   │   ├── add   
      │   │   │   │   │   ├── CMakeLists.txt        //用于编译可执行文件
      │   │   │   │   │   ├── test_add_impl.py      //算子实现代码的测试用例文件
      │   │   │   │   │   ├── test_add_proto.cc    //算子原型定义代码的测试用例文件
      │   │   │   │   ├── CMakeLists.txt             //用于编译可执行文件
      │   │   │   │   ├── test_main.cc              //测试用例调用总入口
      │   │   │   ├ CMakeLists.txt
  2. 在中标麒麟和银河麒麟运行时,请在“testcases/ops_test/add/CMakeLists.txt”文件中添加加粗内容,其他操作系统请忽略此步骤。
    add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
    set(CMAKE_CXX_FLAGS "-std=c++11")   
    set(PROJECT_DIR "$ENV{PROJECT_PATH}")
    set(GTEST_DIR ${PROJECT_DIR}/testcases/libs/gtest)
    set(ADK_DIR "$ENV{ADK_PATH}")
    set(ATC_DIR ${ADK_DIR}/atc)
    set(OP_PROTO_SRC_DIR ${PROJECT_DIR}/op_proto)
    
    message(STATUS "ATC_DIR=${ATC_DIR}")
    
    enable_testing()
    
    include_directories(
            "${GTEST_DIR}/include"
            "${ATC_DIR}/include"
            "${OP_PROTO_SRC_DIR}"
            )
    
    aux_source_directory(${OP_PROTO_SRC_DIR} OP_PROTO_SOURCE_SRCS)
    file(GLOB OP_PROTO_TEST_FILES **proto.cc)
    
    link_directories(
            "${ATC_DIR}/lib64"
            "${GTEST_DIR}"
            "/usr/local/gcc7.3.0/lib64/" 
    )
    
    set(CUSTOM_OBJECT_NAME "add_proto_test")
    
    add_executable(${CUSTOM_OBJECT_NAME}
            ${PROJECT_DIR}/testcases/ut/ops_test/test_main.cc ${OP_PROTO_SOURCE_SRCS} ${OP_PROTO_TEST_FILES})
    
    target_link_libraries(${CUSTOM_OBJECT_NAME} gtest c_sec alog pthread error_manager graph register)

    UT测试需要gcc版本为7.5.0及以上,若gcc版本不满足要求,请升级gcc版本。

  3. 编写算子实现代码的UT Python测试用例,计算出算子执行结果,并取回结果和预期结果进行比较,来测试算子逻辑的正确性。编写算子实现代码的UT Python测试用例的方法有以下两种:
    • 根据UT_Impl模板json文件编写算子实现代码的UT Python测试用例(MindSpore算子同样支持通过UT_Impl模板编写UT Python测试用例)。
      1. 右键单击“testcases/ut/ops_test/add/test_add_impl.py”,选择“Generate TBE UT Impl Case”生成shape为空的算子UT_Impl测试用例定义文件test_add_impl.json。
      2. 在test_add_impl.json文件中,用户需要进行shape信息的配置,用于生成测试数据及测试用例,也可以根据需要进行其他字段的配置,每个字段的详细要求可参见TBE算子UT测试用例定义文件参数解释。若当前字段可选时,支持用户输入None字段,开启开关,将隐藏当前字段的配置项。
      3. UT_Impl测试用例定义文件test_add_impl.json的字段配置完成后,单击“Generate”,test_add_impl.py文件末尾会根据test_add_impl.json文件的配置生成对应的代码。
    • “testcases/ut/ops_test/add/test_add_impl.py”文件中,直接编写算子实现代码的UT Python测试用例。
      import ...
      from op_test_frame.ut import BroadcastOpUT   # 导入UT测试类,可根据算子类型选择使用哪个测试类
      
      ut_case = BroadcastOpUT("add")      # 实例化UT测试用例,ut_case为UT测试框架关键字,不可修改;add为算子的Type
      
      def calc_expect_func(input_x, input_y, output_z):    # 自定义实现生成期望数据的函数
          res = input_x["value"] + input_y["value"]
          return [res, ]    # 返回期望数据
      
      # 添加测试用例
      ut_case.add_precision_case("all", {
          "params": [{"dtype": "float16", "format": "ND", "ori_format": "ND", "ori_shape": (32,), "shape": (32,),
                      "param_type": "input"},
                     {"dtype": "float16", "format": "ND", "ori_format": "ND", "ori_shape": (32,), "shape": (32,),
                      "param_type": "input"},
                     {"dtype": "float16", "format": "ND", "ori_format": "ND", "ori_shape": (32,), "shape": (32,),
                      "param_type": "output"}],
          "calc_expect_func": calc_expect_func
      })
      # 若定义多个用例,定义多个ut_case.add_precision_case函数
      ut_case.add_precision_case("all", {
          "params": [{"dtype": "float16", "format": "ND", "ori_format": "ND", "ori_shape": (16,2), "shape": (16,2),
                      "param_type": "input"},
                     {"dtype": "float16", "format": "ND", "ori_format": "ND", "ori_shape": (16,2), "shape": (16,2),
                      "param_type": "input"},
                     {"dtype": "float16", "format": "ND", "ori_format": "ND", "ori_shape": (16,2), "shape": (16,2),
                      "param_type": "output"}],
          "calc_expect_func": calc_expect_func
      })

      目前Windows版本不支持导入te或者tbe模块。故在编写算子实现代码的UT Python测试用例时不支持导入算子实现文件及涉及te或tbe模块的文件。

      1. 首先导入UT测试类,用户可根据算子类型自行选择使用哪个UT测试类,详细可参见UT测试接口参考
      2. 实例化测试用例,OpUT的使用方法可参见OpUT测试类定义
      3. 用户自定义实现生成期望数据的函数。
      4. 添加测试用例。

        测试用例params中字段和字段取值范围需根据算子实现文件入口参数确定。输入tensor中的"ori_shape"和"ori_format"字段为可选字段,但若使用参数校验修饰器检验参数"ori_shape"和"ori_format"字段必选。

        可参见UT测试接口参考查看每个测试类接口的使用方法。

        若要与期望数据进行结果的比对,请使用add_precision_case接口

  4. 编写算子原型定义的UT C++测试用例。

    “testcases/ut/ops_test/add/test_add_proto.cc”文件中,编写算子原型定义的UT C++测试用例,用于定义算子实例、更新算子输入输出并调用InferShapeAndType函数,最后验证InferShapeAndType函数执行过程及结果的正确性。

    1. 导入gtest测试框架和算子IR定义的头文件。

      UT的C++用例采用的是gtest框架,所以需要导入gtest测试框架;算子原型定义在原型定义头文件中,所以需要导入原型定义的*.h文件。

      //导入gtest框架
      #include <gtest/gtest.h>
      //导入基础的vector类库
      #include <vector>
      //导入算子的IR定义头文件
      #include "add.h"
    2. 定义测试类。

      UT的C++用例采用的是gtest框架,所以需要定义一个类来继承gtest的测试类。

      #include <gtest/gtest.h>
      #include <vector>
      #include "add.h"
      
      class AddTest : public testing::Test {
      protected:
          static void SetUpTestCase() {
              std::cout << "add test SetUp" << std::endl;
      }
      
          static void TearDownTestCase() {
              std::cout << "add test TearDown" << std::endl;
          }
      };

      测试类的名称可自定义,以“Test”为后缀。

    3. 编写测试用例。

      每一个场景写一个测试用例函数,该用例中需要构造算子实例,包括算子名称、shape、数据类型。然后调用InferShapeAndType函数,并将推导出的shape、dtype与预期结果进行对比。

      示例如下:

      TEST_F(AddTest, add_test_case_1) {
          // 定义算子实例及输入shape和type,以TensorDesc实例承载
          ge::op::Add add_op;  //Add为算子的Type,需要与原型定义的REG_OP(OpType)中的OpType保持一致
          ge::TensorDesc tensorDesc;
          ge::Shape shape({2, 3, 4});
          tensorDesc.SetDataType(ge::DT_FLOAT16);
          tensorDesc.SetShape(shape);
          tensorDesc.SetOriginShape(shape);
      
          // 更新算子输入,输入的名称需要与原型定义*.h文件中的名称保持一致,例如:x1与x2分别为Add算子的两个输入
          add_op.UpdateInputDesc("x1", tensorDesc);
          add_op.UpdateInputDesc("x2", tensorDesc);
          // 调用InferShapeAndType函数,InferShapeAndType()接口为固定接口,用例执行时会自动调用算子原型定义中的shape推导函数
          auto ret = add_op.InferShapeAndType();
          // 验证调用过程是否成功
          EXPECT_EQ(ret, ge::GRAPH_SUCCESS);  
      
          // 获取算子输出并比较shape和type,算子输出的名字需要与原型定义*.h文件中的名称保持一致,例如:算子的输出为y
          auto output_desc = add_op.GetOutputDesc("y");
          EXPECT_EQ(output_desc.GetDataType(), ge::DT_FLOAT16);
          std::vector<int64_t> expected_output_shape = {2, 3, 4};
          EXPECT_EQ(output_desc.GetShape().GetDims(), expected_output_shape);
      }
      

      若不同输入的shape不同,请自行定义多个TensorDesc对象进行设置,例如:

          ge::op::Operator1 operator1_op;  //Operator1为算子的Type
          ge::TensorDesc tensorDesc1;
          ge::TensorDesc tensorDesc2;
          ge::Shape shape1({2, 3, 4});
          ge::Shape shape2({3, 4, 5});
          tensorDesc1.SetDataType(ge::DT_FLOAT16);
          tensorDesc1.SetShape(shape1);
          tensorDesc1.SetOriginShape(shape1);
          tensorDesc2.SetDataType(ge::DT_FLOAT16);
          tensorDesc2.SetShape(shape2);
          tensorDesc2.SetOriginShape(shape2);
      
          // 更新算子输入
          operator1_op.UpdateInputDesc("x1", tensorDesc1);
          operator1_op.UpdateInputDesc("x2", tensorDesc2);

执行UT测试用例

  1. 运行算子实现文件的UT测试用例。
    开发人员可以执行当前工程中所有算子的UT测试用例,也可以执行单个算子的UT测试用例。
    • 右键单击“testcases/ut/ops_test”文件夹,选择“Run Tbe Operator‘All’UT Impl with coverage”,执行整个文件夹下算子实现代码的测试用例。
    • 右键单击“testcases/ut/ops_test/算子名称”文件夹,选择“Run Tbe Operator‘算子名称’UT Impl with coverage”,执行单个算子实现代码的测试用例。
    • 右键单击“testcases/ut/ops_test/算子名称/test_算子名称_impl.py”文件,选择“Run Tbe Operator‘算子名称’UT Impl with coverage”,执行单个算子实现代码的测试用例。

    Windows版本的MindStudio在进行以下操作时需获取UT Case Names,如图1所示将出现进度提示框(预计耗时10s左右)。

    • 执行算子实现代码的测试用例时需获取UT Case Names。
    • 在运行配置页面变更参数配置(Soc Version和Operator Name)时需重新获取UT Case Names。
    图1 获取UT Case Names
    第一次运行时会弹出运行配置页面,如图2所示,根据实际情况配置完成后单击“Run”。后续如需修改运行配置,请参考修改运行任务配置
    图2 运行配置页面
    表1 运行配置信息

    参数

    说明

    Name

    运行配置名称,用户可以自定义。

    Test Type

    选择ut_impl。

    Compute Unit

    选择计算单元,可选参数如下:

    • AI Core/Vector Core
    • AI CPU

    选择不同的计算单元可以实现AI Core/Vector Core和AI CPU UT测试配置界面的切换。

    SoC Version

    下拉选择当前版本的昇腾AI处理器类型。

    Target

    运行环境。

    • Simulator_Function:功能仿真环境。
    • Simulator_Performance:性能仿真环境。该功能仅支持昇腾310P AI处理器
    • Simulator_TMModel:快速展示算子执行的调度流水线,不进行实际算子计算。该功能仅支持昇腾310 AI处理器昇腾910 AI处理器

    Enable Advisor

    开启专家系统。

    当Target为Simulator_TMModel时,可以对单测试用例性能进行专家系统分析。专家系统请参见算子工程入口

    Operator Name

    选择运行的测试用例。

    • all表示运行所有用例。
    • 其他表示运行某个算子下的测试用例。

    CANN Machine

    CANN工具所在设备的deployment信息。

    说明:

    仅支持Windows操作系统。

    Case Names

    勾选需要运行的测试用例,即算子实现代码的UT Python测试用例。支持全选和全不选所有测试用例。

  2. 查看运行结果。

    运行完成后,通过界面下方的“Run”日志打印窗口查看运行结果。

    1. 若配置算子期望函数"calc_expect_func": calc_expect_func,运行成功后,日志会打印对比结果。
      • Error count:误差大于绝对容忍率(atol)的数量。
      • Max atol error count:误差大于期望值 * 最大容忍率(max_atol)的数量。
      • Threshold count (rtol * data_size):允许超过自定义精度的最大错误 (相对容忍率(rtol) * tensor元素数量)数量。

      测试结果:

      • Max atol error count>0则UT测试失败。
      • Error count>Threshold count则UT测试失败。
    2. 在“Run”窗口中单击index.html的URL(URL中的localhost为MindStudio安装服务器的IP,建议直接单击打开),查看UT测试用例的覆盖率结果。

      查看UT测试用例运行结果需要使用浏览器,如果未安装浏览器,请用户自行安装。

      如果出现"Page'http://***.html'requested without authorization, you can copy URL and open it in browser to trust it."提示,请参考配置不受信任的网址访问浏览器解决。

    3. 在html页面中单击对应算子,进入UT用例覆盖率详情页面,如图3所示,通过绿色和红色标签区分是否覆盖。
      图3 UT覆盖率详情页面

    4. 运行完成后,生成结果如下所示:
      • 如果在配置运行信息选择的“Target”“Simulator_Performance”,可以在Profiling窗口查看执行流水线,如下图所示。

        Parallel Analysis:并行度视图。并行度视图展示单算子运行中各个指令执行的并行度情况,横轴为时间(Tick,时钟周期),纵轴为各指令单元,鼠标移动到时间块上,可以显示单条指令的消耗时间以及相关指令。

        • “Start”“End”表示数据展示的时间范围。“End”为Cycle数,此数值越大,代表运行时间越长。图中数据展示的时间范围可通过滚动鼠标放大或缩小进行变更。
        • 右键单击时间块,弹出跳转到Profiling指令流视图和TBE、CCE、Assembly源代码菜单。
      • 如果在配置运行信息选择的“Target”“Simulator_TMModel”,可以查看执行流水线,如下图所示。

        若用户使用TIK方式实现算子开发,MindStudio UT测试支持流线图到TIK代码和CCE代码的跳转,帮助用户快速定位到流水图中对应的代码位置,配置详情请参见设置代码跳转功能

        在芯片进行运算前,vector、cube、MTE1、MTE2、MTE3等单元会做初始化操作,对应在timeline显示上会出现数据还未搬运,各个单元就产生流水数据。

      • 如果在配置运行信息勾选了“Enable Advisor”,可以查看专家建议,详情请参见分析结果展示。可以通过单击按钮,显示和隐藏专家建议。
  3. 运行算子原型定义的UT测试用例。

    开发人员可以执行当前工程中所有算子的UT测试用例,也可以执行单个算子的UT测试用例。

    • 右键单击“testcases/ut/ops_test”文件夹,选择“Run Tbe Operator‘All’UT Proto”,执行整个文件夹下算子原型定义代码的测试用例。
    • 右键单击“testcases/ut/ops_test/算子名称”文件夹,选择“Run Tbe Operator‘算子名称’UT Proto”,执行单个算子原型定义代码的测试用例。
    • 右键单击“testcases/ut/ops_test/算子名称/test_算子名称_proto.cc”文件,选择“Run Tbe Operator‘算子名称’UT Proto”,执行单个算子原型定义代码的测试用例。
    第一次运行时会弹出运行配置页面,请参考配置,然后单击“Run”。后续如需修改运行配置,请参考修改运行任务配置
    表2 运行配置信息

    参数

    说明

    Name

    运行配置名称,用户可以自定义。

    Test Type

    选择ut_proto。

    Compute Unit

    选择计算单元

    • AI Core/Vector Core
    • AI CPU

    选择不同的计算单元可以实现AI Core/Vector Core和AI CPU UT测试配置界面的切换。

    Operator Name

    选择运行的测试用例。

    • all表示运行所有用例。
    • 其他表示运行某个算子下的测试用例。

    Case Names

    勾选需要运行的测试用例,即TEST_F中定义的用例。支持全选和全不选所有测试用例。

  4. 查看运行结果。

    运行完成后,通过界面下方的日志打印窗口,查看运行结果。结果中展示此次运行测试用例、成功用例和失败用例的数量,如下图所示。

OP Tiling UT测试

动态shape算子工程涉及OP Tiling时执行以下操作,不涉及tiling实现的算子无需关注。

  1. 创建OP Tiling的实现文件。
    1. 右键单击op_tiling文件夹,选择New > File
    2. 在弹出的New File界面,输入{op_name}.cc,也可以自定义名称,需为.cc文件,如下图所示。

    3. 回车后生成空白的{op_name}.cc文件,用户可根据业务需求编写该文件。
  2. 创建OP Tiling UT测试用例。
    1. 创建UT测试用例,有以下三种入口:

      右键单击算子工程根目录,选择New Cases > TBE OP TILING UT Case

      若已经存在了算子的UT测试用例,可以右键单击“testcases”目录,或者“testcases > ut”目录,选择New Cases > TBE OP TILING UT Case,创建OP Tiling UT测试用例。

    2. 在弹出的算子选择界面,选择需要生成OP Tiling UT模板工程的算子,单击“OK”,如下图所示。

      若已存在此算子的OP Tiling UT测试用例,系统会提示“testcases/ut/ops_tiling_test/xx already exists. Do you want to overwrite?”

      可以选择“Overwrite”或者“Cancel”

      创建完成后,会在算子工程根目录下生成testcases文件夹,目录结构如下所示:

      ├── MyOperator            //工程根目录  
      │   ├──  testcases                            
      │   │   ├── libs                  // gtest框架,为第三方依赖,用户无需关注
      │   │   ├──  ut                              
      │   │   │   ├── ops_tiling_test
      │   │   │   │   ├──add
      │   │   │   │   │   ├── CMakeLists.txt        //用于编译可执行文件
      │   │   │   │   │   ├── test_add_tiling.cc      //算子tiling的测试用例文件
      │   │   │   │   ├── CMakeLists.txt             //用于编译可执行文件
      │   │   │   │   ├── test_main.cc              //测试用例调用总入口
  3. 运行OP Tiling UT测试用例。

    开发人员可以执行当前工程中所有算子的OP Tiling UT测试用例,也可以执行单个算子的OP Tiling UT测试用例。

    • 右键单击“testcases/ut/ops_tiling_test”文件夹,选择“Run TBE Operator‘All’UT OP Tiling”,执行整个文件夹下算子原型定义代码的测试用例。
    • 右键单击“testcases/ut/ops_tiling_test/算子名称”文件夹,选择“Run TBE Operator‘算子名称’UT OP Tiling”,执行单个算子原型定义代码的测试用例。
    • 右键单击“testcases/ut/ops_tiling_test/算子名称/test_算子名称_tiling_.cc”文件,选择“Run TBE Operator‘算子名称’UT Tiling”,执行单个算子原型定义代码的测试用例。
    第一次运行时会弹出运行配置页面,请参考配置,然后单击“Run”。后续如需修改运行配置,请参考修改运行任务配置
    表3 运行配置信息

    参数

    说明

    Name

    运行配置名称,用户可以自定义。

    Test Type

    选择ut_tiling。

    Compute Unit

    计算单元,选择AI Core/Vector Core。

    Operator Name

    选择运行的测试用例。

    • all表示运行所有用例。
    • 其他表示运行某个算子下的测试用例。

    Case Names

    勾选需要运行的测试用例,即TEST_F中定义的用例。

    支持全选和全不选所有测试用例。

  4. 查看运行结果。

    运行完成后,通过界面下方的日志打印窗口,查看运行结果。结果中展示此次一共运行几个用例,成功几个,失败几个。如图4所示。

    图4 运行结果
搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词