Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std::bad_alloc when used in std::thread #103

Open
romain-martin opened this issue Aug 9, 2023 · 0 comments
Open

std::bad_alloc when used in std::thread #103

romain-martin opened this issue Aug 9, 2023 · 0 comments

Comments

@romain-martin
Copy link

First of all, thanks for your work.
I integrated your C++ version in my project and it works very well.
I'm building Eigen and my project on Linux using C++17, without fancy flags and everything works well.
To handle more efficiently several video streams I tried to use std::thread, however I get an issue:

Even if I only create one std::thread, I run into a std::bad_alloc error.
In fact the error seems to happen in KalmanFilter.cpp, in the unfreeze() method at l118
double x1 = box1[0];
It seems that after some time (~40 frames processed) new_history.at(secondLastNotNullIndex)[0] is empty.
I can't figure why, it only happens when using std::thread.

Here is how I do:

{  
    size_t imageBatchLength = imageBatch.size();
    std::vector<std::future<std::vector<int>>> future_crop;
    // process each images in the dataBatch
    for (int imgIdx = 0; imgIdx < imageBatchLength; ++imgIdx) {
        auto image = imageBatch.operator[]<Image<cv::cuda::GpuMat>>(imgIdx);
        if (_activatedCameras.find(image.getStreamId()) == _activatedCameras.end() ||
            !_activatedCameras.at(image.getStreamId()))
        {
            future_crop.emplace_back(std::future<std::vector<int>>());
        }
        else
        {          
            auto future = std::async(std::launch::async, &TrackingNode::processDetections, this,
                                 image.getMatrix(), detectionsBatch.operator[]<YoloDetections>(imgIdx), image.getStreamId(), false);
            future_crop.emplace_back(std::move(future));
        }       
    }
    for (int imgIdx = 0; imgIdx < imageBatchLength; ++imgIdx) {
        if(!future_crop[imgIdx].valid())
        {
            db.emplaceBack(std::vector<int>());
            continue;
        }
        std::vector<int> trackerBoxes = future_crop[imgIdx].get();
        if(trackerBoxes.empty())
        {
            db.emplaceBack(std::vector<int>());
        }
        else
        {
            db.emplaceBack(trackerBoxes); 
        }
    }
    return db;
}

And the function I call asynchronously is defined here:

std::vector<int> TrackingNode::processDetections(const cv::cuda::GpuMat& image, const YoloDetections& detections,
                                                 const std::string& camId, bool isSubFrame) {
 std::vector<int> indexes; // to save original detections indexes and being able to reassign tracking ids at the right detection
 std::vector<DetectedObject> fullObjectList;
 YoloDetections toTrackObjects;
 for (int i = 0; i < detections.size(); ++i) {
     fullObjectList.push_back(detections[i]);
     if (std::find(_labelFilters[camId].begin(), _labelFilters[camId].end(), fullObjectList[i].getObjectName()) !=
         _labelFilters[camId].end()) {
         toTrackObjects.emplaceDetectedObject(fullObjectList[i]);
         indexes.push_back(i);
     }
 }
 std::vector<int> results(fullObjectList.size(), -1);
 if (_labelFilters.find(camId) == _labelFilters.end())
     return results;
 auto res = _trackers[camId].update(ocsort::Vector2Matrix(toTrackObjects, image, _classes[camId]));
 // assign ids to the right object index
 for (int j = 0; j < res.size(); ++j) {
     results[indexes[j]] = res[j][4];
 }
 return results;
}

Where _trackers is an std::map<std::string,ocsort::OCSort>

So I have a different OCSort object for each thread I launch, however it doesn't seems to be the issue here as I only launch one thread.

What is weird though is that running the same code, with just removing the std::thread part, calling "processDetections" synchronously, everything is fine.

Does someone already faced this issue or have any clue of why this happen?
Thank you

@romain-martin romain-martin changed the title std::bad_alloc when using in std::thread std::bad_alloc when used in std::thread Aug 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant