[run_pull] Reading from stream was aborted! Error

I am currently facing issues while porting from Hailo15 to Hailo8L and would like to seek assistance regarding this matter.

I created a number of threads equal to the worker count to process the detected face images for Head Pose Estimation.

This was done in parallel using a ThreadPool. This approach has been confirmed to work correctly with Hailo15 and HailoRT version 4.17.0.

However, when I applied the same approach using Hailo8L, I encountered errors during the Vstream write/read operations starting from the second thread, which prevents normal operation.

bool writeInput(hailort::InputVStream& inputVstream, const cv::Mat& frame) {
    int height = frame.rows;
    int width = frame.cols;
    
    auto status = inputVstream.write(hailort::MemoryView(frame.data, height * width * 3));
    if (status != HAILO_SUCCESS) {
        ERROR_LOG("writeInput FAILED %d", status);
        return false;
    }
    DEBUG_LOG("writeInput SUCCESS");
    return true;
}

bool readOutput(hailort::OutputVStream& outputVstream, std::vector<uint8_t>& outputBuffer) {
    outputBuffer.clear();
    outputBuffer.resize(outputVstream.get_frame_size());
    auto status = outputVstream.read(hailort::MemoryView(outputBuffer.data(), outputBuffer.size()));
    if (status != HAILO_SUCCESS) {
        ERROR_LOG("readOutput FAILED %d", status);
        return false;
    }
    DEBUG_LOG("readOutput SUCCESS");
    return true;
}

For reference, I am using Hailort version 4.17.1 for Hailo15 and version 4.20.0 for Hailo8L + raspberrypi.

I have also attached the hailort.log file where the error occurred.
There are abort logs like this.

"[2025-04-04 07:40:48.880] [3579] [HailoRT] [info] [edge_elements.cpp:396] [run_pull] Reading from stream was aborted!
[2025-04-04 07:40:48.880] [3581] [HailoRT] [info] [edge_elements.cpp:396] [run_pull] Reading from stream was aborted!
[2025-04-04 07:40:48.880] [3579] [HailoRT] [info] [queue_elements.cpp:738] [run_in_thread] run_pull of queue element PullQEl_hw_read1my_hopenet3/fc2 was aborted!
[2025-04-04 07:40:48.880] [3581] [HailoRT] [info] [queue_elements.cpp:738] [run_in_thread] run_pull of queue element PullQEl_hw_read0my_hopenet3/fc3 was aborted!"

I have reviewed the Hailort application example code and guides, and found that the example code and execution flow are similar.
However, an abort occurs at the NPU level, making it unclear what specific aspects I should investigate.

Hey @yesul.min,

Welcome to the Hailo Community!

From the logs you shared, especially that “Reading from stream was aborted!” error, it’s definitely a threading problem. I ran into something similar recently.

The core issue is that VStreams on Hailo-8 aren’t thread-safe. When your code creates a thread per detected face and they all try to access shared VStream objects concurrently, it leads to resource conflicts and those “Reading from stream was aborted!” errors.

How I fixed it:

Option 1: Synchronized Access (Simpler Implementation)

// Create a single instance of VStreams (input & output)
std::shared_ptr<hailort::InputVStream> input_vstream = /* your existing stream */;
std::shared_ptr<hailort::OutputVStream> output_vstream = /* your existing stream */;

// Add mutex for synchronization
std::mutex io_mutex;

// Modified worker function
void process_face(cv::Mat face_crop) {
    std::lock_guard<std::mutex> lock(io_mutex);
    // Now only one thread can access VStreams at a time
    writeInput(*input_vstream, face_crop);
    readOutput(*output_vstream, output_buffer);
    // Process results...
}

This approach is minimally invasive to your existing code - just add the mutex and lock guard.

Option 2: Isolated VStreams (Better Performance)

// In your thread worker function:
void process_face_isolated(cv::Mat face_crop) {
    // Create thread-local network group and streams
    auto network_group = device.create_configured_network_group(hef_file);
    
    // Build thread-specific VStreams
    auto input_vstream = VStreamsBuilder::create_input_vstreams(...)[0];
    auto output_vstream = VStreamsBuilder::create_output_vstreams(...)[0];
    
    // Each thread now has its own isolated streams
    writeInput(*input_vstream, face_crop);
    readOutput(*output_vstream, output_buffer);
    // Process results...
}

This approach aligns better with Hailo’s examples on async inference and multi-model setups, where each context is isolated.
I did the second option and it worked for me (hailo examples).

Please try one of these and update me on the progress !