ES Overview

This section describes a simplified graph construction method to improve usability.

Eager Style (ES) is a set of function-style graph construction APIs. It is so named because its syntax closely resembles that of the Torch Eager mode script. In ES, edges are connected and Intermediate Representation (IR) information is transferred through functions. Compared with the method of constructing a graph from the operator prototype (or IR), ES graph construction requires less code, improving the usability and foolproof capability. The following figure shows the overall logic.

ES consists of three key components:

  • ES basic data structure: provides basic data structure APIs such as EsGraphBuilder and EsTensorHolder for ES graph construction. For details, see C/C++ APIs.
  • ES Code Generator: reads operator prototypes and generates the executable program of the graph construction API for each operator.
  • Generated ES graph construction API: is generated by the ES Code Generator during construction or is included in the CANN software package. You can directly use it.

The ES graph construction APIs have the following features:

  • Are obtained through automatic CodeGen based on operator prototypes.
  • Support multiple languages: C, C++, and Python.
  • Support forward and backward compatibility from the API, ABI, and IR semantics dimensions.

Mappings Between ES Graph Construction APIs and IRs

The mapping logic between ES graph construction APIs and IRs remains consistent across all three languages. Each IR is mapped to a function, and the function name is obtained from the IR type (the Es prefix is added before the C API). The function parameters correspond to the inputs and attributes of the operator, and the return value corresponds to the output.

For example, the IR prototype of the operator Foo is defined as follows:

1
2
3
4
5
6
7
REG_OP(Foo)
    .INPUT(x1)
    .INPUT(x2)
    .OUTPUT(y1)
    .ATTR(a1, Int, 10)
    .ATTR(a2, Int, 20)
    .OP_END_FACTORY_REG(Foo)

In the preceding IR prototype definition, the operator type is Foo, the inputs are x1 and x2, the output is y1, and the attributes are a1 and a2 (the default values are 10 and 20, respectively). In the ES graph construction API, the corresponding function prototype is as follows:

  • Function name: Foo (C++/Python) or EsFoo (C).
  • Parameters: x1, x2, a1, and a2.
  • Return value: the output, y1.

According to the preceding principles, the generated function prototype for ES graph construction APIs is as follows:

  • C
    1
    EsCTensorHolder* EsFoo(EsCTensorHolder* x1, EsCTensorHolder* x2, int64_t a1,  int64_t a2);
    
  • C++
    1
    2
    3
    4
    5
    namespace ge {
    namespace es {
    EsTensorHolder Foo(const EsTensorLike &x1, const EsTensorLike &x2, int64_t a1 = 10,  int64_t a2 = 20);
    }
    }
    

    In C++:

    1. TensorLike is used to express the input to support the case where the argument can directly transfer values, for example, Foo(t0, float(1.0)).
    2. To indicate that some attributes in the IR prototype are optional, you can set default parameters in the function prototype for ES graph construction APIs.
  • Python
    1
    def Foo(x1: Union[TensorHolder, TensorLike] , x2: Union[TensorHolder, TensorLike], *, a1: int = 10, a2 : int = 20) -> TensorHolder:
    

    In Python, positional arguments represent inputs, while keyword arguments represent attributes. This method can clearly distinguish inputs from attributes and facilitate extension and compatibility.

Header File/Module Split Policies

Each IR prototype corresponds to an independent header file (C and C++) and a Python module (.py) in ES. For example, the ES header file generated for the preceding Foo IR prototype is as follows:

  • C: es_Foo_c.h
  • C++: es_Foo.h
  • Python: es_Foo.py

In addition, to improve the usage experience of multiple languages, ES provides an aggregation API. For details about the naming rules of a header file and an aggregation file, see Product Description.