Skip to content

cv::cuda::HoughSegmentDetector crashes when used in multiple threads #3184

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

Closed
4 tasks done
mitul93 opened this issue Feb 28, 2022 · 0 comments · Fixed by #3185
Closed
4 tasks done

cv::cuda::HoughSegmentDetector crashes when used in multiple threads #3184

mitul93 opened this issue Feb 28, 2022 · 0 comments · Fixed by #3185

Comments

@mitul93
Copy link
Contributor

mitul93 commented Feb 28, 2022

cv::cuda::HoughSegmentDetector crashes when used in multiple threads because it uses texture reference.

A texture reference is similar to global memory which is not thread-safe.

The current implementation of HoughSegmentDetector uses texture reference. See here :

texture<uchar, cudaTextureType2D, cudaReadModeElementType> tex_mask(false, cudaFilterModePoint, cudaAddressModeClamp);

For CV_CUDEV_ARCH > =300, CUDA implementation should instead use texture objects. This already has been implemented in opencv_contrib but for a different algorithm. Specifically, cv::cuda::createCannyEdgeDetector in this commit : 6ca24c8

I already have an implementation which solves this problem for cv::cuda::HoughSegmentDetector() based on cv::cuda::createCannyEdgeDetector() implementation.

I will submit a PR with this solution shortly.

System information (version)
  • OpenCV => 4.5.5-dev
  • Operating System / Platform => Ubuntu 18.04
  • Compiler => gcc
Detailed description

See above.

Code to reproduce

This code launches 5 threads and each executes probabilistic hough segment detector on a sample image 1000 times.
When two threads are trying to access the texture reference (which behaves similar to global memory), the code crashes.

#include <iostream>
#include <opencv2/opencv.hpp>
#include "opencv2/cudaimgproc.hpp"
#include <pthread.h>

#define NUM_THREADS 5
#define NUM_IMG_PER_THREAD 1000

cv::Mat testImg;

void *findHough(void *threadid) {
    uint64_t threadNo = (uint64_t)threadid;

    cv::Ptr<cv::cuda::HoughSegmentDetector> hough = cv::cuda::createHoughSegmentDetector(1.0f, (float) (CV_PI / 180.0f), 50, 5);

    for(int i=0; i<NUM_IMG_PER_THREAD; i++) {
        cv::cuda::Stream stream;

        cv::cuda::GpuMat d_lines;
        cv::cuda::GpuMat srcImgGpu;

        cv::Mat houghLines;
        srcImgGpu.upload(testImg, stream);
        hough->detect(srcImgGpu, d_lines, stream);
        d_lines.download(houghLines, stream);
        stream.waitForCompletion();

        std::cout << "Thread, " << threadNo << ", index, " << i << ",Found #lines, " << houghLines.cols << std::endl;
    }

    return NULL;
}

int main()
{
    std::cout << "Test case for hough segmentation cuda crash..." << std::endl;

    std::cout << "Reading test image..." << std::endl;
    testImg = cv::imread("./sample_img/test_img_4k.jpg", cv::IMREAD_GRAYSCALE);

    if (testImg.empty()) {
        std::cout << "Test image empty." << std::endl;
        return -1;
    } else {
        std::cout << "Test image reading successful." << std::endl;
    }

    pthread_t threads[NUM_THREADS];

    int rc;
    uint64_t i;

    for( i = 0; i < NUM_THREADS; i++ ) {
      rc = pthread_create(&threads[i], NULL, findHough, (void *) i);
      
      if (rc) {
         std::cout << "Error:unable to create thread," << rc << std::endl;
         exit(-1);
      }
   }

   for (int i = 0; i < NUM_THREADS; i++) {
       pthread_join(threads[i], NULL);
   }
    
    return 0;
}
    

Here's the crash log.

root@df29f8235b3a:/src/testdata# ./hough_crash_reproduce 
Test case for hough segmentation cuda crash...
Reading test image...
Test image reading successful.
Thread, 4, index, 0,Found #lines, 4096
Thread, 3, index, 0,Found #lines, 4096
Thread, 1, index, 0,Found #lines, 4096
Thread, 0, index, 0,Found #lines, 4096
...
Thread, 4, index, 21,Found #lines, 4096
terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(4.5.3) /opencv_contrib-4.5.3/modules/cudaimgproc/src/cuda/hough_segments.cu:234: error: (-217:Gpu API call) an illegal memory access was encountered in function 'houghLinesProbabilistic_gpu'
terminate called recursively

terminate called recursively
Aborted (core dumped)

I'm attaching the test image that was used to reproduce the crash. However, any image can be used to reproduce this bug.
test_img_4k

Issue submission checklist
  • I report the issue, it's not a question
  • I checked the problem with documentation, FAQ, open issues,
    forum.opencv.org, Stack Overflow, etc and have not found any solution
  • I updated to the latest OpenCV version and the issue is still there
  • There is reproducer code and related data files: videos, images, onnx, etc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants