2 * Copyright (c) 2020-2023 Hailo Technologies Ltd. All rights reserved.
3 * Distributed under the MIT license (https://opensource.org/licenses/MIT)
6 * @file async_infer_functionality_example.cpp
7 * This example demonstrates the Async Infer API usage with a specific model with multiple inputs and outputs
8 * and changes configutrations of the streams.
11 #include "hailo/hailort.hpp"
19 #define FRAMES_COUNT (100)
21 using namespace hailort;
23 static std::shared_ptr<uint8_t> page_aligned_alloc(size_t size)
26 auto addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
27 if (MAP_FAILED == addr) throw std::bad_alloc();
28 return std::shared_ptr<uint8_t>(reinterpret_cast<uint8_t*>(addr), [size](void *addr) { munmap(addr, size); });
29 #elif defined(_MSC_VER)
30 auto addr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
31 if (!addr) throw std::bad_alloc();
32 return std::shared_ptr<uint8_t>(reinterpret_cast<uint8_t*>(addr), [](void *addr){ VirtualFree(addr, 0, MEM_RELEASE); });
34 #pragma error("Aligned alloc not supported")
40 auto vdevice = VDevice::create();
42 std::cerr << "Failed create vdevice, status = " << vdevice.status() << std::endl;
43 return vdevice.status();
46 auto infer_model_exp = vdevice.value()->create_infer_model("hefs/multi_network_shortcut_net.hef");
47 if (!infer_model_exp) {
48 std::cerr << "Failed to create infer model, status = " << infer_model_exp.status() << std::endl;
49 return infer_model_exp.status();
51 auto infer_model = infer_model_exp.release();
53 infer_model->input("multi_network_shortcut_net_scope1/input_layer_0")->set_format_type(HAILO_FORMAT_TYPE_FLOAT32);
54 infer_model->output("multi_network_shortcut_net_scope1/shortcut0")->set_format_type(HAILO_FORMAT_TYPE_FLOAT32);
55 infer_model->input("multi_network_shortcut_net_scope2/input_layer_1")->set_format_type(HAILO_FORMAT_TYPE_FLOAT32);
56 infer_model->output("multi_network_shortcut_net_scope2/shortcut1")->set_format_type(HAILO_FORMAT_TYPE_FLOAT32);
58 auto configured_infer_model = infer_model->configure();
59 if (!configured_infer_model) {
60 std::cerr << "Failed to create configured infer model, status = " << configured_infer_model.status() << std::endl;
61 return configured_infer_model.status();
64 // We store buffers vector here as a guard for the memory. The buffer will be freed only after
65 // configured_infer_model will be released.
66 std::vector<std::shared_ptr<uint8_t>> buffer_guards;
68 auto bindings = configured_infer_model->create_bindings();
70 std::cerr << "Failed to create infer bindings, status = " << bindings.status() << std::endl;
71 return bindings.status();
74 for (const auto &input_name : infer_model->get_input_names()) {
75 size_t input_frame_size = infer_model->input(input_name)->get_frame_size();
76 auto input_buffer = page_aligned_alloc(input_frame_size);
77 auto status = bindings->input(input_name)->set_buffer(MemoryView(input_buffer.get(), input_frame_size));
78 if (HAILO_SUCCESS != status) {
79 std::cerr << "Failed to set infer input buffer, status = " << status << std::endl;
83 buffer_guards.push_back(input_buffer);
86 for (const auto &output_name : infer_model->get_output_names()) {
87 size_t output_frame_size = infer_model->output(output_name)->get_frame_size();
88 auto output_buffer = page_aligned_alloc(output_frame_size);
89 auto status = bindings->output(output_name)->set_buffer(MemoryView(output_buffer.get(), output_frame_size));
90 if (HAILO_SUCCESS != status) {
91 std::cerr << "Failed to set infer output buffer, status = " << status << std::endl;
95 buffer_guards.push_back(output_buffer);
98 AsyncInferJob last_infer_job;
99 for (uint32_t i = 0; i < FRAMES_COUNT; i++) {
100 // Waiting for available requests in the pipeline
101 auto status = configured_infer_model->wait_for_async_ready(std::chrono::milliseconds(1000));
102 if (HAILO_SUCCESS != status) {
103 std::cerr << "Failed to wait for async ready, status = " << status << std::endl;
107 auto job = configured_infer_model->run_async(bindings.value(), [] (const AsyncInferCompletionInfo &/*completion_info*/) {
108 // Use completion_info to get the job status and the corresponding bindings
111 std::cerr << "Failed to start async infer job, status = " << job.status() << std::endl;
116 if (i == FRAMES_COUNT - 1) {
117 last_infer_job = job.release();
121 // Wait for last infer to finish
122 auto status = last_infer_job.wait(std::chrono::milliseconds(1000));
123 if (HAILO_SUCCESS != status) {
124 std::cerr << "Failed to wait for infer to finish, status = " << status << std::endl;
128 return HAILO_SUCCESS;