更新时间:2021-03-18 GMT+08:00
分享

编译算子

函数声明

算子编译函数的声明如下所示:

Status BuildTeBinxx(const ge::Operator& op, TEBinInfo& te_bin_info)

其中:

  • BuildTeBinxx:函数名称,用户自定义,需要保持唯一。
  • op:目标算子模型,适配昇腾AI处理器的离线模型的算子数据结构,保存算子信息,Operator类的详细描述请参见《GE API参考》中的“Operator类接口”
  • te_bin_info:存储自定义算子二进制文件路径、算子描述文件路径以及DDK的版本信息。TEBinInfo结构体的详细描述请参见《Framework API参考》中的“TEBinBuildFn函数”

实现流程

算子编译函数在离线模型生成器进行模型转换时调用,主要完成以下流程:

  • 获取算子张量描述信息以及算子属性,模型转换时,这些信息都需要是确定值,用于进行算子的匹配。

    例如,如下所示,模型转换时只匹配axis为1、输入张量Shape的Dim为4的Reduction算子。

       //解析算子属性operation
        ge::AttrValue operationAttrValue;
        if ((ge::GRAPH_SUCCESS != op.GetAttr("operation", operationAttrValue)) || (ge::GRAPH_SUCCESS != operationAttrValue.GetValue<AttrValue::STR>(operation)))
        {
               printf("GetOpAttr operation failed!\n");
        }
    
        // 解析算子属性axis ,并调整axis指向Mylenet网络中Reduction算子的上一层Softmax算子的实际输出维度,即轴1的位置。
        ge::AttrValue axisAttrValue;
        if ((ge::GRAPH_SUCCESS != op.GetAttr("axis", axisAttrValue)) || (ge::GRAPH_SUCCESS != axisAttrValue.GetValue<AttrValue::INT>(axis)))
        {
            printf("GetOpAttr axis failed!\n");
        }
        // In the OM model, all shape are supplemented to 4d. In this case, axis needs to be repaired to point to the original 2d.
        if(axis < 0)
            axis -= 2;
    
        // 解析算子属性coeff
        ge::AttrValue coeffAttrValue;
        if ((ge::GRAPH_SUCCESS != op.GetAttr("coeff", coeffAttrValue)) || (ge::GRAPH_SUCCESS != coeffAttrValue.GetValue<AttrValue::FLOAT>(coeff)))
        {
            printf("GetOpAttr coeff failed!\n");
        }
        // 获取算子输入张量描述信息
        TensorDesc input_desc      = op.GetInputDesc(0);
    
        // 解析Input shape并校验算子的Dim是否为4
        if(input_desc.GetShape().GetDimNum() != 4)
        {
            printf("The shape size is %d, which is not 4!", (int32_t)input_desc.GetShape().GetDimNum());
            return FAILED;
        }
  • 指定算子实现文件、算子实现函数以及内核名。
        FilePath   = "project_path/operator/reduction";    //算子实现文件所在的绝对路径+算子py文件名称
        FuncName   = "Reduction";                //算子实现文件中算子实现函数的名称。          
        KernelName = "Reduction";                //算子实现文件中算子实现函数中定义的kernel_name,即生成的二进制文件的名称。
  • 指定算子编译生成的算子描述文件(*.json)文件的路径,请保持如下固定配置。
      te_bin_info.json_file_path = "./kernel_meta/" + KernelName + ".json";

    模型转换时,会从此路径中读取算子的二进制描述文件,获取算子相关信息。

    执行omg模型转换命令时,会根据FilePath中配置的算子实现的路径拷贝算子编译生成的kernel_meta文件夹到执行omg命令时所在的路径,所以*.json文件相对于执行omg命令所在目录的路径固定为“./kernel_meta”。

  • 调用te::BuildCustomop函数来调用算子实现文件的python函数编译算子。

    BuildCustomop函数调用如下所示:

    te::BuildTeCustomOp(te_bin_info.ddk_version, op.GetName(), FilePath, FuncName,"(i,i,i,i), s, i, s, f, s", input_desc.GetShape().GetDim(0),input_desc.GetShape().GetDim(1),input_desc.GetShape().GetDim(2),input_desc.GetShape().GetDim(3), "float16", axis, operation.c_str(), coeff,KernelName.c_str());
    其中:
    • te_bin_info.ddk_version:DDK的版本信息,固定参数。后续模型转换时会自动传入DDK版本信息。
    • op.GetName( ):获取算子名称,固定参数。
    • FilePath:前面定义的算子文件所在相对路径。
    • FuncName:算子实现文件中的算子实现函数名称。
    • "(i,i,i,i), s, i, s, f, s":代表算子实现文件中实现函数的参数占位符,其中i表示整形,s表示字符串类型,f表示单精度浮点数类型,o表示PyObject*类型。占位符需要和后面紧跟的参数顺序和类型保持一致,同时需要和算子实现文件中的算子实现函数的定义保持一致。BuildCustomop会根据这些参数调用算子实现函数,再通过TVM机制生成内核。
分享:

    相关文档

    相关产品