Help Center/ Atlas 300 Application (Model 3000)/ Matrix API Reference/ Process Orchestration APIs/ API Usage Example/ Example of Using C++ APIs (Creating a Graph Based on the Configuration File)
Updated on 2022-03-13 GMT+08:00

Example of Using C++ APIs (Creating a Graph Based on the Configuration File)

/**
* @file graph_cplusplus_api_example.cpp
*
* Copyright(C), 2017 - 2017, Huawei Tech. Co., Ltd. ALL RIGHTS RESERVED.
*
* @Source Files for HIAI Graph Orchestration
*
* @version 1.0
*
*/
#include <unistd.h>
#include <thread>
#include <fstream>
#include <algorithm>

#include "hiaiengine/api.h"
#include "user_def_data_type.h"

/**************************************************************************
* Normally the mandatory steps to set up the whole HIAI graph include:
*  1) Call the HIAI_Init() API to perform global system initialization;
*  2) Call HIAI_CreateGraph or Graph::CreateGraph to create and start a graph.
*  3) Set profile config if necessary.
*  4) Call HIAI_DestoryGraph or Graph::DestroyGraph to destroy the graph finally.
*
***************************************************************************/


// Just define variables which are used in only this example
// and are not required in real user case.
#define MATRIX_USER_SPECIFY_ENGINE_PRIORITY (10)

static uint32_t g_graph_id = 100;
static uint32_t src_engine_id = 1000; // Defined in graph.prototxt
static uint32_t dest_engine_id = 1002; // Defined in graph.prototxt
static std::string graph_config_proto_file = "./config/graph.prototxt";
// Define End

namespace hiai {

class GraphDataRecvInterface: public DataRecvInterface
{
public:
    GraphDataRecvInterface()
    {
    }

    /**
    * @ingroup hiaiengine
    * @brief   Read and save the data.
    * @param [in] in_data   Input data
    * @return HIAI Status
    */
    HIAI_StatusT RecvData(const std::shared_ptr<void>& message)
    {
       // Convert the data to a specific message type and process the related message. For example:
        // shared_ptr<std::string> data = 
        // std::static_pointer_cast<std::string>(message);
        return HIAI_OK;
    }
private:
};
}

/*************************************************************************
* HIAIEngine Example
* Graph:
* SrcEngine<-->Engine<-->DestEngine
*
*************************************************************************/
HIAI_StatusT HIAI_InitAndStartGraph()
{
    // Step1: Global System Initialization before using Matrix
    HIAI_StatusT status = HIAI_Init(0);

    // Step2: Create and Start the Graph
    status = hiai::Graph::CreateGraph(graph_config_proto_file);
    if (status != HIAI_OK)
    {
        HIAI_ENGINE_LOG(status, "Fail to start graph");
        return status;
    }

    // Step3: Set the callback function to receive data.
    std::shared_ptr<hiai::Graph> graph = hiai::Graph::GetInstance(g_graph_id);
    if (nullptr == graph)
    {
        HIAI_ENGINE_LOG("Fail to get the graph-%u", g_graph_id);
        return status;
    }

    // Specify the port id (default to zero)
    hiai::EnginePortID target_port_config;
    target_port_config.graph_id = g_graph_id;
    target_port_config.engine_id = dest_engine_id;
    target_port_config.port_id = 0;

    graph->SetDataRecvFunctor(target_port_config,
        std::shared_ptr<hiai::GraphDataRecvInterface>(
        new hiai::GraphDataRecvInterface()));

    return HIAI_OK;
}


// User Application Main Example
int main()
{
    HIAI_StatusT ret = HIAI_OK;

    // Creation process
    ret = HIAI_InitAndStartGraph();

    if(HIAI_OK != ret)
    {
        HIAI_ENGINE_LOG("Fail to start graph");;
        return -1;
    }

    // Read data and inject data into the process.
    std::shared_ptr<hiai::Graph> graph = hiai::Graph::GetInstance(g_graph_id);
    if (nullptr == graph)
    {
        HIAI_ENGINE_LOG("Fail to get the graph-%u", g_graph_id);
        return -1;
    }

    hiai::EnginePortID engine_id;
    engine_id.graph_id = g_graph_id;
    engine_id.engine_id = src_engine_id;
    engine_id.port_id = 0;

    bool is_end_of_data = false;
    while (!is_end_of_data)
    {
        std::shared_ptr<UserDefDataType> user_def_msg(new UserDefDataType);

        // Read data and pad UserDefDataType. For details about the data type registration, see the corresponding section in this document.
       // Inject data to the graph.
        if (HIAI_OK != graph->SendData(engine_id, "UserDefDataType",
            std::static_pointer_cast<void>(user_def_msg)))
        {
            // When the queue is full, a message is returned indicating that sending data fails. The service logic determines whether to resend or discard the data.
            HIAI_ENGINE_LOG("Fail to send data to the graph-%u", g_graph_id);
            break;
        }
    }

   // After the processing is complete, delete the entire graph.
    hiai::Graph::DestroyGraph(g_graph_id);
    return 0;
}