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

Usage Example for C++ APIs (Creating a Graph Based on the Configuration File and Writing the Generated Graph to the List)

/**
* @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 setup 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 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:
};
}
/*************************************************************************
* Matrix Example
* Graph:
* SrcEngine<-->Engine<-->DestEngine
*
*************************************************************************/
HIAI_StatusT HIAI_InitAndStartGraph(std::list<std::shared_ptr<hiai::Graph>>& graphList)
{
    // 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, graphList);
    if (status != HIAI_OK)
    {
        HIAI_ENGINE_LOG(status, "Fail to start graph");
        return status;
    }
    // Step3: Set the callback function to receive data.
   // If multiple graphs are configured in a configuration file, you can traverse the graph list to obtain the corresponding graph and perform the expected operation.
    std::list<std::shared_ptr<hiai::Graph>>::iterator iter = graphList.begin();
    std::shared_ptr<hiai::Graph> graph = hiai::Graph::GetInstance((*iter)->GetGraphId());
    if (nullptr == graph)
    {
        HIAI_ENGINE_LOG("Fail to get the graph");
        return status;
    }
    // Specify the port id (default to zero)
    hiai::EnginePortID target_port_config;
    target_port_config.graph_id = (*iter)->GetGraphId();
    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;
    // Store the graphs created by the user.
    std::list<std::shared_ptr<hiai::Graph>> graphList;
    // Creation process
    ret = HIAI_InitAndStartGraph(graphList);
    if(HIAI_OK != ret)
    {
        HIAI_ENGINE_LOG("Fail to start graph");;
        return -1;
    }
    // Read data and inject data into the process.
    std::list<std::shared_ptr<hiai::Graph>>::iterator iter = graphList.begin();
    std::shared_ptr<hiai::Graph> graph = hiai::Graph::GetInstance((*iter)->GetGraphId());
    if (nullptr == graph)
    {
        HIAI_ENGINE_LOG("Fail to get the graph");
        return -1;
    }
    hiai::EnginePortID engine_id;
    engine_id.graph_id = (*iter)->GetGraphId();
    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", (*iter)->GetGraphId());
            break;
        }
    }
   // After the processing is complete, delete all graphs.
    std::list<std::shared_ptr<hiai::Graph>>::iterator graphIter;
    for (graphIter = graphList.begin(); graphIter != graphList.end(); ++graphIter) {
        hiai::Graph::DestroyGraph((*graphIter)->GetGraphId());
    }
    return 0;
}