Updated on 2022-03-13 GMT+08:00

Calling Example

Example 1: Synchronous Calling

The current example is the implementation code of the inference engine in the case of a single model.

In the case of multiple models, pay attention to the following points if you need to refer to this example:

  • The preOutBuffer variable cannot contain the static keyword. You need to define the variable as follows:
    bool preOutBuffer = false;
  • Before calling the Process function, call the AddPara function to set the name of each model.
    ai_context.AddPara("model_name", modelName);// Multiple models. You must set the seperate model name for each model.
    ret = ai_model_manager_->Process(ai_context,
            inDataVec, outDataVec_, 0);

The sample code is as follows:

// Process function implementation of the inference engine
HIAI_IMPL_ENGINE_PROCESS("ClassifyNetEngine", ClassifyNetEngine, CLASSIFYNET_ENGINE_INPUT_SIZE)
{
    HIAI_ENGINE_LOG(this, HIAI_OK, "ClassifyNetEngine Process");
    HIAI_StatusT ret = HIAI_OK;
    static bool preOutBuffer = false;
    std::vector<std::shared_ptr<hiai::IAITensor>> inDataVec;

    // Obtain the data input by the previous engine.
    std::shared_ptr<EngineTransNewT> input_arg =
        std::static_pointer_cast<EngineTransNewT>(arg0);
    // If the input data is a null pointer, an error code is returned
    if (nullptr == input_arg)
    {
        HIAI_ENGINE_LOG(this, HIAI_INVALID_INPUT_MSG,
            "fail to process invalid message");
        return HIAI_INVALID_INPUT_MSG;
    }

    // Prepare output data. If the synchronization mechanism is used, use the HIAI_DMalloc interface to allocate memory for the output data, and use the CreateTensor interface to provide memory for algorithm inference.
    //If the Process function for inference is called, the output memory needs to be allocated for only once.
    if (preOutBuffer == false) {
        std::vector<hiai::TensorDimension> inputTensorVec;
        std::vector<hiai::TensorDimension> outputTensorVec;
        ret = ai_model_manager_->GetModelIOTensorDim(modelName, inputTensorVec, outputTensorVec);
        if (ret != hiai::SUCCESS)
        {
            HIAI_ENGINE_LOG(this, HIAI_AI_MODEL_MANAGER_INIT_FAIL,
                "hiai ai model manager init fail");
            return HIAI_AI_MODEL_MANAGER_INIT_FAIL;
        }
        // allocate OutData in advance
        HIAI_StatusT hiai_ret = HIAI_OK;
        for (uint32_t index = 0; index < outputTensorVec.size(); index++) {
            hiai::AITensorDescription outputTensorDesc = hiai::AINeuralNetworkBuffer::GetDescription();
            uint8_t* buffer = nullptr;
            //Allocate the memory by calling the HIAI_Dmalloc interface. The memory is used for algorithm inference and can be released by calling the HIAI_DFree interface.
            //Release the memory during engine destruction.
            hiai_ret = hiai::HIAIMemory::HIAI_DMalloc(outputTensorVec[index].size, (void*&)buffer, 1000);
            if (hiai_ret != HIAI_OK || buffer == nullptr) {
                std::cout<<"HIAI_DMalloc failed"<< std::endl;
                continue;
            }
            outData_.push_back(buffer);
            shared_ptr<hiai::IAITensor> outputTensor =
                hiai::AITensorFactory::GetInstance()->CreateTensor(outputTensorDesc, buffer, outputTensorVec[index].size);
            outDataVec_.push_back(outputTensor);
        }
        preOutBuffer = true;
    }

    // Transfer buffer to Framework directly, only one inputsize
    hiai::AITensorDescription inputTensorDesc =
        hiai::AINeuralNetworkBuffer::GetDescription();
    shared_ptr<hiai::IAITensor> inputTensor =
        hiai::AITensorFactory::GetInstance()->CreateTensor(inputTensorDesc,
        input_arg->trans_buff.get(), input_arg->buffer_size);
    // AIModelManager. fill in the input data.
    inDataVec.push_back(inputTensor);

    hiai::AIContext ai_context;
    // Process work
    ret = ai_model_manager_->Process(ai_context,
        inDataVec, outDataVec_, 0);
    if (hiai::SUCCESS != ret)
    {
        HIAI_ENGINE_LOG(this, HIAI_AI_MODEL_MANAGER_PROCESS_FAIL,
            "Fail to process ai model manager");
        return HIAI_AI_MODEL_MANAGER_PROCESS_FAIL;
    }

    // Convert the generated data to the buffer of the string type and send the data.
    for (uint32_t index = 0; index < outDataVec_.size(); index++)
    {
        HIAI_ENGINE_LOG(this, HIAI_OK, "ClassifyNetEngine SendData");
        std::shared_ptr<hiai::AINeuralNetworkBuffer> output_data = std::static_pointer_cast<hiai::AINeuralNetworkBuffer>(outDataVec_[index]);
        std::shared_ptr<std::string> output_string_ptr =
            std::shared_ptr<std::string>(new std::string((char*)output_data->GetBuffer(), output_data->GetSize()));
        hiai::Engine::SendData(0, "string",
            std::static_pointer_cast<void>(output_string_ptr));
    }
    inDataVec.clear();
    return HIAI_OK;
}

ClassifyNetEngine::~ClassifyNetEngine() {
    //Release the pre-allocated memory of outData.
    HIAI_StatusT ret = HIAI_OK;
    for (auto buffer : outData_) {
        if (buffer != nullptr) {
            ret = hiai::HIAIMemory::HIAI_DFree(buffer);
            buffer = nullptr;
        }
    }
 }

Example 2: Asynchronous Calling

For details, see ddk/sample/customop/customop_app/main.cpp under the DDK installation directory in the DDK sample.