hailo-ai / Hailo-Application-Code-Examples

MIT License
58 stars 33 forks source link

Class Implementation for cpp #264

Closed observa24 closed 3 months ago

observa24 commented 4 months ago

Hello,

I am writing a cpp app which has multiple options for the device to run the inference on e.g. hailo, orin, .... Thus, I want to implement hailo inference as a class and call its "infer" method to run the inference. All the examples I see have the configuration in the main function but do not implement it as a class. I tried an implementation like the following code but I get the following when I try to run inference:

Failed to write data to the device
[HailoRT] [error] CHECK failed - Trying to write to vstream efnet0/input_layer1 before its network group is activated

My code is: hailoRT.h

#include "hailo/hailort.hpp"
#include "modelBase.h"

class hailoRT : public modelBase
{
public:
    hailoRT(std::string modelFilePath);
    ~hailoRT();
    bool infer(uint8_t *inputImage, uint8_t *output);

private:
    std::unique_ptr<hailort::Device> device;
    hailort::ConfiguredNetworkGroupVector networkGroups;
    std::pair<std::vector<hailort::InputVStream>, std::vector<hailort::OutputVStream>> vStreams;

    bool build();
    bool hefInfo(std::pair<std::vector<hailort::InputVStream>, std::vector<hailort::OutputVStream>> &vstreams);
};

hailoRT.cpp

#include "hailoRT.h"

hailoRT::hailoRT(std::string modelFilePath) : modelBase(modelFilePath)
{
    if (!this->build())
    {
        std::cerr << "Failed to build the network!" << std::endl;
    }
    this->hefInfo(vStreams);
}
hailoRT::~hailoRT()
{
}
bool hailoRT::infer(uint8_t *inputImage, uint8_t *output)
{
    hailo_status status = this->vStreams.first[0].write(hailort::MemoryView(inputImage, 224 * 224 * 3 * sizeof(uint8_t)));
    if (status != HAILO_SUCCESS)
    {
        std::cerr << "Failed to write data to the device" << std::endl;
        return false;
    }
    status = this->vStreams.second[0].read(hailort::MemoryView(output, this->vStreams.second[0].get_frame_size()));
    if (status != HAILO_SUCCESS)
    {
        std::cerr << "Failed to read data from the device" << std::endl;
        return false;
    }
    return true;
}

bool hailoRT::build()
{
    // Open hailo8 device
    std::vector<hailo_pcie_device_info_t> allDevices = hailort::Device::scan_pcie().release();
    this->device = hailort::Device::create_pcie(allDevices.at(0)).release();
    if (!device)
    {
        std::cerr << "Failed to create pcie device!" << std::endl;
        return false;
    }

    // Configure network through hef
    auto hef = hailort::Hef::create(this->modelFilePath);
    if (!hef)
    {
        std::cerr << "Failed to open the hef file: " << this->modelFilePath << std::endl;
        return false;
    }

    auto configureParams = hef->create_configure_params(HAILO_STREAM_INTERFACE_PCIE);
    if (!configureParams)
    {
        std::cerr << "Failed to create configure params!" << std::endl;
        return false;
    }

    this->networkGroups = std::move((*device).configure(hef.value(), configureParams.value()).release());
    // if (!networkGroups)
    // {
    //     std::cerr << "Failed to configure groups!" << std::endl;
    //     return false;
    // }

    if (1 != networkGroups.size())
    {
        std::cerr << "Invalid amount of network groups" << std::endl;
        return false;
    }
    auto networkGroup = networkGroups.at(0);

    auto inputVstreamParams = networkGroup->make_input_vstream_params(true, HAILO_FORMAT_TYPE_UINT8, HAILO_DEFAULT_VSTREAM_TIMEOUT_MS, HAILO_DEFAULT_VSTREAM_QUEUE_SIZE);
    auto outputVstreamParams = networkGroup->make_output_vstream_params(false, HAILO_FORMAT_TYPE_FLOAT32, HAILO_DEFAULT_VSTREAM_TIMEOUT_MS, HAILO_DEFAULT_VSTREAM_QUEUE_SIZE);
    auto inputVstreams = hailort::VStreamsBuilder::create_input_vstreams(*networkGroup, inputVstreamParams.value());
    auto outputVstreams = hailort::VStreamsBuilder::create_output_vstreams(*networkGroup, outputVstreamParams.value());

    if (!inputVstreams or !outputVstreams)
    {
        std::cerr << "Failed creating input: " << inputVstreams.status() << " output status:" << outputVstreams.status() << std::endl;
        return inputVstreams.status();
    }

    this->vStreams = std::make_pair(inputVstreams.release(), outputVstreams.release());

    auto activatedNetworkGroup = networkGroup->activate();
    if (!activatedNetworkGroup)
    {
        std::cerr << "Failed to activate the network group " << activatedNetworkGroup.status();
        return false;
    }

    return true;
}

bool hailoRT::hefInfo(std::pair<std::vector<hailort::InputVStream>, std::vector<hailort::OutputVStream>> &vstreams)
{

    std::cout << "-I---------------------------------------------------------------------" << std::endl;
    std::cout << "-I- Dir  Name                                     " << std::endl;
    std::cout << "-I---------------------------------------------------------------------" << std::endl;
    for (auto &value : vstreams.first)
    {
        std::string info_str = value.get_info().name;
        info_str += " (";
        info_str += std::to_string(value.get_info().shape.height);
        info_str += ", ";
        info_str += std::to_string(value.get_info().shape.width);
        info_str += ", ";
        info_str += std::to_string(value.get_info().shape.features);
        info_str += ")";
        std::cout << "-I- IN:  " << info_str << std::endl;
    }
    std::cout << "-I---------------------------------------------------------------------" << std::endl;
    for (auto &value : vstreams.second)
    {
        std::string info_str = value.get_info().name;
        info_str += " (";
        info_str += std::to_string(value.get_info().shape.height);
        info_str += ", ";
        info_str += std::to_string(value.get_info().shape.width);
        info_str += ", ";
        info_str += std::to_string(value.get_info().shape.features);
        info_str += ")";
        std::cout << "-I- OUT: " << info_str << std::endl;
    }
    std::cout << "-I---------------------------------------------------------------------" << std::endl;
    return true;
}

It would be great if you can refer me to such an example or guide me on how I can do it.

Thanks!