How to Perform Tiling Debugging

During project-based operator development, you need to implement the tiling function, whose prototype is fixed and takes TilingContext as the input. The framework builds TilingContext and calls the tiling function. If independent tiling debugging is required, you can use OpTilingRegistry to load the built tiling dynamic library, obtain the pointer to the tiling function, and call the function. When the function is called, TilingContext, the input parameter of the tiling function, is built using ContextBuilder.

The procedure is as follows:

  1. Implement the operator by referring to the procedure of project-based operator development, and obtain the corresponding tiling dynamic library file through OPP build or dynamic operator library build.
    • OPP build: The dynamic library corresponding to the tiling implementation is liboptiling.so in the OPP deployment directory. For details about the path, see Operator Package Deployment.
    • Dynamic library build: The tiling implementation is integrated in the dynamic operator library libcust_opapi.so. For details about the path, see Dynamic and Static Operator Library Build.
  2. Write test code.
    • Use ContextBuilder to configure the shape, data type, format, platform information, and other information of the input and output tensors to build TilingContext.
    • Call the LoadTilingLibrary API of OpTilingRegistry to load the tiling dynamic library, and call the GetTilingFunc API to obtain the pointer to the tiling function.
    • Execute the tiling function and verify its correctness.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    // test.cpp
    #include <iostream>
    #include "exe_graph/runtime/storage_shape.h"
    #include "tiling/context/context_builder.h"
    
    int main()
    {
        gert::StorageShape x_shape = {{2, 32}, {2, 32}};
        gert::StorageShape y_shape = {{2, 32}, {2, 32}};
        gert::StorageShape z_shape = {{2, 32}, {2, 32}};
    
        auto param = gert::TilingData::CreateCap(4096);
        auto workspace_size_holder = gert::ContinuousVector::Create<size_t>(4096);
        auto ws_size = reinterpret_cast<gert::ContinuousVector *>(workspace_size_holder.get());
    
        auto holder = context_ascendc::ContextBuilder()
                                    .NodeIoNum(2, 1)
                                    .IrInstanceNum({1, 1})
                                    .AddInputTd(0, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND, x_shape)
                                    .AddInputTd(1, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND, y_shape)
                                    .AddOutputTd(0, ge::DT_FLOAT, ge::FORMAT_ND, ge::FORMAT_ND, z_shape)
                                    .TilingData(param.get())
                                    .Workspace(ws_size)
                                    .AddPlatformInfo("Ascendxxxyy")
                                    .BuildTilingContext();
        auto tilingContext = holder->GetContext<gert::TilingContext>();
        context_ascendc::OpTilingRegistry tmpIns;
        bool flag = tmpIns.LoadTilingLibrary("/your/path/to/so_path/liboptiling.so");  // Load the corresponding tiling dynamic library file.
        if (flag == false) {
            std::cout << "Failed to load tiling so" << std::endl;
            return -1;
        }
        context_ascendc::TilingFunc tilingFunc = tmpIns.GetTilingFunc("AddCustom");  // Obtain the tiling function corresponding to the AddCustom operator. The input parameter is OpType.
        if (tilingFunc != nullptr) {
            ge::graphStatus ret = tilingFunc(tilingContext);  // Execute the tiling function.
            if (ret != ge::GRAPH_SUCCESS) {
                std::cout << "Exec tiling func failed." << std::endl;
                return -1;
            }
        } else {
            std::cout << "Get tiling func failed." << std::endl;
            return -1;
        }
        return 0;
    }
    
  3. Compile the test code.
    1
    g++ test.cpp -I${INSTALL_DIR}/include  -L${INSTALL_DIR}/lib64 -Wl,-rpath,${INSTALL_DIR}/lib64 -ltiling_api -lc_sec -lgraph_base -lregister -lascendalog -lplatform -o test
    
    • Replace ${INSTALL_DIR} with the CANN component directory. For example, if the installation is performed by the root user, the default file storage path is /usr/local/Ascend/cann.
    • Link the dependent dynamic libraries as required. The following dynamic libraries must be linked:
      • libtiling_api.so: dynamic library related to tiling APIs, including the ContextBuilder class and OpTilingRegistry class.
      • libc_sec.so: security function library, on which libtiling_api.so depends.
      • libgraph_base.so: basic data structure and API library, on which libtiling_api.so depends.
      • libregister.so: library related to service function registration (such as tiling function registration and operator prototype registration).
      • libascendalog.so: log library, on which libtiling_api.so depends.
      • libplatform.so: platform information library, on which libtiling_api.so depends. This library is required when the tiling function uses hardware platform information.
  4. Run the executable file.
    1
    ./test