昇腾社区首页
中文
注册

基于ST测试样例

简介

命令行场景下,开发者可以直接基于Ascend开源社区samples仓中提供的算子测试样例代码进行修改,适配自己的算子测试代码。

样例获取:单击GiteeGithub,进入Ascend samples开源仓,参见README中的“版本说明”下载配套版本的sample包,从“cplusplus/level1_single_api/4_op_dev/2_verify_op”目录中获取样例。

ST测试用例实现思路

ST测试用例的实现思路为:进行算子测试用例json文件的定义,将自定义算子转换成单个算子的离线模型文件(*.om),然后使用AscendCL(Ascend Computing Language)提供的单算子模型加载接口加载离线模型,并传入算子输入数据,进行算子执行,通过查看输出结果验证算子功能是否正确,如下图所示。

图1 自定义算子ST测试详细流程

下面详细讲解基于样例代码实现自定义算子ST测试用例的步骤。

配置算子测试用例定义文件(*.json)

自定义算子json文件用于进行算子的描述,需要按照算子原型定义进行配置,包括算子的输入、输出及属性信息。

固定shape算子配置示例如下所示:

[
{
      "op": "ReshapeCust",
      "input_desc": [
        {
          "format": "ND",
          "shape": [9],
          "type": "int32"
        },
        {
          "format": "ND",
          "shape": [2],
          "type": "int32"
        }
      ],
      "output_desc": [
        {
          "format": "ND",
          "shape": [3,3],
          "type": "int32"
        }
      ]
    }
]

动态shape算子配置示例如下所示:

[
  {
    "op": "xxx",
    "input_desc": [
      {
        "format": "ND",
        "shape": [-1,16],
        "shape_range": [[0, 32]],
        "type": "int64"
      },
      {
        "format": "ND",
        "shape": [-1,16],
        "shape_range": [[0, 32]],
        "type": "int64"
      }
    ],
    "output_desc": [
      {
        "format": "ND",
        "shape": [-1,16],
        "shape_range": [[0,32]],
        "type": "int64"
      }
    ]
  }
]

自定义算子json文件的参数说明及更多的配置样例可参见ATC工具使用指南的“高级功能>单算子模型转换”。

使用ATC工具生成单算子模型文件

  1. 请参见环境准备,配置CANN软件所需基本环境变量。
  2. 使用ATC工具,加载单算子描述文件(json文件)生成单算子的离线模型。

    atc --singleop=test_data/config/xxx.json --soc_version=${soc_version} --output=op_models

    • singleop:算子描述的json文件,为相对于执行atc命令所在目录的相对路径。
    • soc_version:请配置为用户当前实际使用的昇腾AI处理器BS9SX1A AI处理器的型号。
      昇腾AI处理器BS9SX1A AI处理器的型号可通过如下方式查看:
      1. 单击如下手册中的链接并进入该手册,Ascend-DMI工具用户指南
      2. 完成使用前准备,然后进入使用工具>设备实时状态查询章节。
      3. 使用相关命令查看芯片的详细信息,例如使用ascend-dmi -i -dt命令查看芯片的详细信息,返回信息中“Chip Name”对应取值(将大写字母转换为小写,并去掉中间空格)即为具体使用的${soc_version}
    • output:生成的模型文件的存储路径,为相对于执行atc命令所在目录的相对路径。

    ATC工具的其他参数解释请参考ATC工具使用指南中的转换样例

构造输入数据

进行单算子验证的AscendCL代码实现前,开发者需要自行构造算子测试数据的二进制文件,二进制文件以input_x.bin命名,x请从0开始命名,例如input_0.bin,input_1.bin

AscendCL算子测试代码实现

  1. 构造算子描述对象。

    Ascend开源社区中提供了单算子验证样例代码,开发者可直接基于样例代码进行修改。

    样例获取:单击GiteeGithub,进入Ascend samples开源仓,参见README中的“版本说明”下载配套版本的sample包,从“cplusplus/level1_single_api/4_op_dev/2_verify_op/acl_execute_reshape”目录中获取样例。

    修改src/main.cpp文中的CreateOpDesc()函数,构造算子描述对象。

    • 带属性的Conv2D算子的opDesc构造示例如下:
      OperatorDesc CreateOpDesc()
      {
          std::vector<int64_t> shape{8, 512, 7, 7};
          std::string opType = "Conv2D";
          aclDataType dataType = ACL_FLOAT16;
          aclFormat format = ACL_FORMAT_NCHW;
          OperatorDesc opDesc(opType);
          opDesc.AddInputTensorDesc(dataType, shape.size(), shape.data(), format); // Conv2D算子的第一个输入
          std::vector<int64_t> shape1{512,512,3,3};  
          opDesc.AddInputTensorDesc(dataType, shape1.size(), shape1.data(), format);   // Conv2D算子的第二个输入
          std::vector<int64_t> shape2{8, 512, 7, 7};
          opDesc.AddOutputTensorDesc(dataType, shape2.size(), shape2.data(), format);  // Conv2D算子的输出
          int64_t intList[4]{1, 1, 1, 1};
          auto opAttr = opDesc.opAttr;
          aclopSetAttrListInt(opAttr, "strides", 4, intList);
          aclopSetAttrListInt(opAttr, "pads", 4, intList);
          aclopSetAttrListInt(opAttr, "dilations", 4, intList);
          return opDesc;
      }
    • 自定义算子ReshapeCust算的opDesc构造示例如下:
      OperatorDesc CreateOpDesc()
      {
         // define operator
          std::vector<int64_t> inputShape0{9};
          std::vector<int64_t> inputShape1{2};
          std::vector<int64_t> outputShape{3,3};
          std::string opType = "ReshapeCust";
          aclDataType dataType = ACL_INT32;
          aclFormat format = ACL_FORMAT_ND;
          OperatorDesc opDesc(opType);
          opDesc.AddInputTensorDesc(dataType, inputShape0.size(), inputShape0.data(), format);
          opDesc.AddInputTensorDesc(dataType, inputShape1.size(), inputShape1.data(), format);
          opDesc.AddOutputTensorDesc(dataType, outputShape.size(), outputShape.data(), format);
          return opDesc;
      }

    OperatorDesc为“acl_execute_reshape/inc/operator_desc.h”中构造的算子描述对象,其中:

    • std::string opType为算子的类型。
    • std::vector<aclTensorDesc *> inputDesc,为算子的输入描述。
    • std::vector<aclTensorDesc *> outputDesc,为算子的输出描述。
    • aclopAttr *opAttr,为算子的属性。

      调用aclopSetAttr**( )接口进行属性的构造,不同类型的属性调用的aclopSetAttr*的接口不同,详细的接口可参见应用软件开发指南 (C&C++)中的“AscendCL API参考 > 数据类型及其操作接口”章节中的“aclopAttr”类型的接口。

    • OperatorDesc &AddInputTensorDesc(aclDataType dataType, int numDims, const int64_t *dims, aclFormat format)

      用于构造算子的输入,若算子有多个输入,需要使用多条opDesc.AddInputTensorDesc( )语句进行构造。

    • OperatorDesc &AddOutputTensorDesc(aclDataType dataType, int numDims, const int64_t *dims, aclFormat format)

      用于构造算子的输出,若算子有多个输出,需要使用多条opDesc.AddOutputTensorDesc( )语句进行构造。

      aclDataType与aclFormat的取值范围请参见应用软件开发指南 (C&C++)中的“AscendCL API参考 > 数据类型及其操作接口”章节中的“aclDataType”“aclFormat”

  2. 加载单算子模型并进行算子的执行。

    主要包括以下关键接口:

    调用aclInit接口进行AscendCL初始化并调用aclrtSetDevice接口指定用于运算的Device。

    调用aclopSetModelDir接口,设置加载模型文件的目录,目录下存放单算子模型文件(*.om文件)。

    调用aclrtMalloc接口申请Device上的内存,存放执行算子的输入、输出数据。

    根据构造的算子描述信息(输入输出Tensor描述、算子属性等)、申请存放算子输入输出数据的内存,然后调用aclopExecuteV2接口加载并执行算子。

    调用aclrtSynchronizeStream接口阻塞应用运行,直到指定Stream中的所有任务都完成。

    调用aclrtDestroyStream接口释放stream。

    调用aclrtResetDevice接口释放Device上的资源。

    调用aclFinalize接口实现AscendCL去初始化。

    AscendCL接口的详细使用方法可参见应用软件开发指南 (C&C++)中的“AscendCL API参考”

测试用例编译运行

编译测试用例代码,并将生成的动态库文件、单算子模型文件以及测试数据在运行环境执行,详细操作步骤可参见样例参考