Operator IR Registration

Overview

The prototype (or IR) of an operator is used to describe the input, output, and attribute information, and register the operator with the operator prototype library.

To register operator IR, implement the /op_proto/OpName.h file in the project directory of the operator.

The following describes how to implement the header file for operator IR definition.

Implementation

  1. Define the macro.

    Use the following statement to define the operator IR registration macro. The macro name is fixed to GE_OP_OPERATORTYPE_H, where OPERATORTYPE is obtained by capitalizing OpType in the REG_OP(OpType) statement.

    #ifndef GE_OP_OPERATORTYPE_H       // conditional build
    #define GE_OP_OPERATORTYPE_H       // macro definition
  2. Include the header file.

    At the beginning of the operator IR implementation file, add the #include command to include the header file used for operator registration.

    #include "graph/operator_reg.h"

    Find the operator_reg.h file in the include/graph/ directory in the CANN software installation directory. Include this file to use functions, macros, structs, and more related to the operator type registration.

  3. Register the prototype.

    GE provides the REG_OP macro and the INPUT, OUTPUT, and ATTR APIs (cascaded using periods) to register the inputs, outputs, and attribute information of the operator. Operator registration is ended with the OP_END_FACTORY_REG API.

    The registration code is as follows.

    namespace ge{
    REG_OP(OpType) // Operator type
        .INPUT(x1, TensorType({ DT_FLOAT, DT_INT32 }))
        .INPUT(x2, TensorType({ DT_FLOAT, DT_INT32 })) 
        // .OPTIONAL_INPUT(b, TensorType{DT_FLOAT}) 
        // .DYNAMIC_INPUT(x, TensorType{DT_FLOAT, DT_INT32})       
        .OUTPUT(y, TensorType({ DT_FLOAT, DT_INT32 })) 
        // .DYNAMIC_OUTPUT(y, TensorType{DT_FLOAT, DT_INT32})
        .ATTR(x, Type, DefaultValue)
        // .REQUIRED_ATTR(x, Type)
        // .GRAPH(z1)
        // .DYNAMIC_GRAPH(z2)
        .OP_END_FACTORY_REG(OpType)
    }
    • Registering the operator type
      REG_OP(OpType)

      OpType: operator type registered to the custom operator library of Ascend AI Processor. The name must not conflict with existing operator names.

    • Registering operator inputs

      Operator inputs are classified into required inputs, optional inputs, and dynamic multi-inputs (the number of inputs is not fixed). Each input needs to be registered in one of the following modes based on its type.

      Table 1 Input registration

      Input Type

      Registration Mode

      Required input

      INPUT(x1, TensorType({ DT_FLOAT,DT_UINT8,... }))

      Description:

      Registers the required input information of an operator.

      • x: a macro parameter, which indicates the input name of the operator and is user-defined.
      • TensorType({ DT_FLOAT,DT_UINT8,... }): Enclose a list of input data types in { }. For the full list of the supported data types, see DataType. Class TensorType defines supported data types for certain APIs. For details, see TensorType.

      If the operator has multiple required inputs, describe each input separately with one statement: INPUT(x, TensorType({ DT_FLOAT,DT_UINT8,... })).

      Optional input

      OPTIONAL_INPUT(x, TensorType{DT_FLOAT, ...})

      Description:

      Registers an optional operator input.
      • x: a macro parameter for the input name.
      • TensorType{DT_FLOAT, ...}: Enclose a list of input data types in the { }. For the full list of the supported data types, see DataType. Class TensorType defines supported data types for certain APIs. For details, see TensorType.

      Dynamic multi-input

      DYNAMIC_INPUT(x, TensorType{DT_FLOAT, DT_INT32, ...})

      Description:

      Registers the input information for a dynamic multi-input operator. Dynamic multi-input operators, for example, the AddN operator, refer to operators whose input quantity is uncertain and can be determined only at run time.
      • x: a macro parameter for the input name. At graph run time, x0, x1, x2, and more are automatically generated based on the number of inputs. The inputs are numbered from 0 in ascending order.

        The input x of the AddN operator is registered as follows:

        .DYNAMIC_INPUT(x, TensorType::NumberType()
      • TensorType({ DT_FLOAT,DT_UINT8,... }): Enclose a list of input data types in { }. For the full list of the supported data types, see DataType. Class TensorType defines supported data types for certain APIs. For details, see TensorType.
    • Registering operator outputs

      Operator outputs are classified into required outputs and dynamic multi-outputs (the number of outputs is not fixed). Each output needs to be registered in either of the following modes based on its type.

      Table 2 Output registration

      Output Type

      Registration Mode

      Required output

      OUTPUT(y, TensorType({ DT_FLOAT,DT_UINT8,... }))

      Description:

      Registers the output information of an operator.
      • y: a macro parameter, which indicates the output name of the operator and is user-defined.
      • TensorType({DT_FLOAT, DT_UINT8, ...}): Enclose a list of output data types in the { }. For the full list of the supported data types, see DataType. Class TensorType defines supported data types for certain APIs. For details, see TensorType.

      If the operator has multiple required outputs, register each with a separate statement OUTPUT(x, TensorType({DT_FLOAT, DT_UINT8, ...})).

      Dynamic multi-output

      DYNAMIC_OUTPUT(y, TensorType{DT_FLOAT, DT_INT32})

      Description:

      Registers the output information for a dynamic multi-output operator.
      • y: a macro parameter for the output name. At graph run time, y0, y1, y2, and more are automatically generated based on the number of outputs. The outputs are numbered from 0 in ascending order.
      • TensorType({DT_FLOAT, DT_UINT8, ... }): Enclose a list of output data types in the { }. For the full list of the supported data types, see DataType. Class TensorType defines supported data types for certain APIs. For details, see TensorType.
    • Registering operator attributes

      Operator attributes are classified into required attributes and optional attributes. Each attribute needs to be registered in either of the following modes based its type.

      Table 3 Attribute registration

      Attribute Type

      Registration Mode

      Optional attribute

      ATTR(x, Type, DefaultValue)

      Description:

      Registers the optional attributes of an operator, including the attribute name, type, and default value. The default value is used if the attribute is not specified with a value. For details about the values of Type, see Prototype Definition (REG_OP).

      For example, ATTR(mode, Int, 1) registers an int64_t attribute named mode with default value 1.

      If an operator has multiple optional attributes, each optional attribute must be registered using an ATTR(x, Type, DefaultValue) statement.

      Required attribute

      REQUIRED_ATTR(x, Type)

      Description:

      Registers the required attributes of an operator, including the attribute name and type. No default values are provided. Therefore, you have to set attribute values for each operator object. For details about the values of Type, see Prototype Definition (REG_OP).

      If an operator has multiple required attributes, each required attribute must be registered using an REQUIRED_ATTR(x, Type) statement.

    • Registering the subgraph information contained in an operator

      If an operator consists of multiple operators, it forms a subgraph, which needs to be registered. Subgraph registration is generally used for control operators (such as selection operators and iteration operators). Subgraphs are classified into static subgraphs and dynamic subgraphs. You can select either of the following registration modes based on the subgraph type.

      Table 4 Subgraph registration

      Subgraph Type

      Registration Mode

      Static subgraph

      GRAPH(z1)

      Description:

      Registers the subgraph information contained in the operator. Replace z1 with the subgraph name, which is applicable to control operators such as selection operators and iteration operators.

      After the registration is complete, APIs related to subgraphs are generated, which are used to obtain the subgraph name and subgraph description, set the subgraph description, and build IR models. For the full list of APIs, see GRAPH. Ensure that each subgraph of an operator has a unique name.

      Dynamic subgraph

      DYNAMIC_GRAPH(z2)

      Description:

      Registers the subgraph information in a dynamic operator. Replace z2 with the subgraph name, which is applicable to control operators such as selection operators and iteration operators.

      After the registration is complete, APIs related to dynamic subgraphs are generated, which are used to create dynamic subgraphs and set the subgraph description, and build IR models. For the full list of APIs, see DYNAMIC_GRAPH. Ensure that each subgraph of an operator has a unique name.

    • Ending operator registration
      OP_END_FACTORY_REG(OpType)

      The OpType argument must be consistent with that of REG_OP(OpType).

  4. End conditional build.
    #endif