Skip to content

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

@mitul93

Description

@mitul93

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions