Ask Your Question

Revision history [back]

OpenCV OpenCL Thread Saftey - Deadlock (changing cv::Mat to UMat)

I've been converting an OpenCV program from using cv::Mat to cv::UMat with the intention of increasing performance (which it does). What I'm experiencing is a deadlock in the OpenCL code:

1  __lll_lock_wait                                                                                                                                                                                    lowlevellock.S                 135  0x7fffeeb6626d 
2  __GI___pthread_mutex_lock                                                                                                                                                                          pthread_mutex_lock.c           115  0x7fffeeb5fe42 
3  cv::ocl::OpenCLAllocator::copy(cv::UMatData *, cv::UMatData *, int, unsigned long const *, unsigned long const *, unsigned long const *, unsigned long const *, unsigned long const *, bool) const                                     0x7ffff2e9b44f 
4  cv::UMat::copyTo(cv::_OutputArray const&) const                                                                                                                                                                                        0x7ffff2ff13c8 
5  cv::UMat::clone                                                                                                                                                                                    mat.inl.hpp                    3685 0x7ffff75b78ff 


1  __lll_lock_wait                                                                                                                                                                                    lowlevellock.S                 135  0x7fffeeb6626d 
2  __GI___pthread_mutex_lock                                                                                                                                                                          pthread_mutex_lock.c           115  0x7fffeeb5fe42 
3  cv::ocl::OpenCLAllocator::copy(cv::UMatData *, cv::UMatData *, int, unsigned long const *, unsigned long const *, unsigned long const *, unsigned long const *, unsigned long const *, bool) const                                     0x7ffff2e9b44f 
4  cv::UMat::copyTo(cv::_OutputArray const&) const                                                                                                                                                                                        0x7ffff2ff13c8 
5  cv::UMat::clone                                                                                                                                                                                    mat.inl.hpp                    3685 0x7ffff75b78ff

The code I'm using is multi-threaded and had no issues at all before using the cv::Mat structure.

It seems the issue occurs on copying the data.

I'm using OpenCV 3.4 on Linux (Ubuntu 16.04) and have tried with both intel and Nvidia GPU cards, both have the same issue.

Is the OpenCL using UMat meant to be thread safe? At no point to I work on the same data in the same thread at the same time. Data is passed between threads by pointers which worked with the Mat structure.

I'm guessing it is suppose to be thread safe as otherwise no need for the lock at all.

Is this a bug or am I doing something wrong? Is there a workaround?

OpenCV OpenCL Thread Saftey - Deadlock (changing cv::Mat to UMat)

I've been converting an OpenCV program from using cv::Mat to cv::UMat with the intention of increasing performance (which it does). What I'm experiencing is a deadlock in the OpenCL code:

1  __lll_lock_wait                                                                                                                                                                                    lowlevellock.S                 135  0x7fffeeb6626d 
2  __GI___pthread_mutex_lock                                                                                                                                                                          pthread_mutex_lock.c           115  0x7fffeeb5fe42 
3  cv::ocl::OpenCLAllocator::copy(cv::UMatData *, cv::UMatData *, int, unsigned long const *, unsigned long const *, unsigned long const *, unsigned long const *, unsigned long const *, bool) const                                     0x7ffff2e9b44f 
4  cv::UMat::copyTo(cv::_OutputArray const&) const                                                                                                                                                                                        0x7ffff2ff13c8 
5  cv::UMat::clone                                                                                                                                                                                    mat.inl.hpp                    3685 0x7ffff75b78ff 


1  __lll_lock_wait                                                                                                                                                                                    lowlevellock.S                 135  0x7fffeeb6626d 
2  __GI___pthread_mutex_lock                                                                                                                                                                          pthread_mutex_lock.c           115  0x7fffeeb5fe42 
3  cv::ocl::OpenCLAllocator::copy(cv::UMatData *, cv::UMatData *, int, unsigned long const *, unsigned long const *, unsigned long const *, unsigned long const *, unsigned long const *, bool) const                                     0x7ffff2e9b44f 
4  cv::UMat::copyTo(cv::_OutputArray const&) const                                                                                                                                                                                        0x7ffff2ff13c8 
5  cv::UMat::clone                                                                                                                                                                                    mat.inl.hpp                    3685 0x7ffff75b78ff

The code I'm using is multi-threaded and had no issues at all before using the cv::Mat structure.

It seems the issue occurs on copying the data.

I'm using OpenCV 3.4 on Linux (Ubuntu 16.04) and have tried with both intel and Nvidia GPU cards, both have the same issue.

Is the OpenCL using UMat meant to be thread safe? At no point to I work on the same data in the same thread at the same time. Data is passed between threads by pointers which worked with the Mat structure.

I'm guessing it is suppose to be thread safe as otherwise no need for the lock at all.

Is this a bug or am I doing something wrong? Is there a workaround?

EDIT:

So, it seems the bug arises due to the double lock on lines 5419 of ocl.cpp

UMatDataAutoLock src_autolock(src); 
UMatDataAutoLock dst_autolock(dst);

When multiple UMats are used. The locks are acquired from

From UMatrix.cpp

enum { UMAT_NLOCKS = 31 }; 
static Mutex umatLocks[UMAT_NLOCKS];


void UMatData::lock() 
{ 
  umatLocks[(size_t)(void*)this % UMAT_NLOCKS].lock();
}

void UMatData::unlock()
{ 
  umatLocks[(size_t)(void*)this % UMAT_NLOCKS].unlock(); 
}

It seems that, it is possible that if (size_t)(void*)this % UMAT_NLOCKS is the same for both the destination and source matrix, this will then take the same lock and try to lock it twice, causing a deadlock. This is definitely a bug in OpenCV.

I've temporally fixed the issue by increasing UMAT_NLOCKS to a much higher number, but this is not optimal