Skip to content

Commit

Permalink
fixed many bugs related to Mat::getUMat(), asynchronous kernel execut…
Browse files Browse the repository at this point in the history
…ion etc. Also, played a bit with ocl::cvtColor vs cv::cvtColor performance
  • Loading branch information
vpisarev committed Nov 30, 2013
1 parent daefe69 commit 6da5d21
Show file tree
Hide file tree
Showing 10 changed files with 400 additions and 207 deletions.
19 changes: 11 additions & 8 deletions modules/core/include/opencv2/core/mat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,21 +279,22 @@ class CV_EXPORTS MatAllocator
//virtual void allocate(int dims, const int* sizes, int type, int*& refcount,
// uchar*& datastart, uchar*& data, size_t* step) = 0;
//virtual void deallocate(int* refcount, uchar* datastart, uchar* data) = 0;
virtual UMatData* allocate(int dims, const int* sizes,
int type, size_t* step) const = 0;
virtual UMatData* allocate(int dims, const int* sizes, int type,
void* data, size_t* step, int flags) const = 0;
virtual bool allocate(UMatData* data, int accessflags) const = 0;
virtual void deallocate(UMatData* data) const = 0;
virtual void map(UMatData* data, int accessflags) const = 0;
virtual void unmap(UMatData* data) const = 0;
virtual void sync(UMatData* u) const;
virtual void map(UMatData* data, int accessflags) const;
virtual void unmap(UMatData* data) const;
virtual void download(UMatData* data, void* dst, int dims, const size_t sz[],
const size_t srcofs[], const size_t srcstep[],
const size_t dststep[]) const = 0;
const size_t dststep[]) const;
virtual void upload(UMatData* data, const void* src, int dims, const size_t sz[],
const size_t dstofs[], const size_t dststep[],
const size_t srcstep[]) const = 0;
const size_t srcstep[]) const;
virtual void copy(UMatData* srcdata, UMatData* dstdata, int dims, const size_t sz[],
const size_t srcofs[], const size_t srcstep[],
const size_t dstofs[], const size_t dststep[], bool sync) const = 0;
const size_t dstofs[], const size_t dststep[], bool sync) const;
};


Expand Down Expand Up @@ -335,8 +336,10 @@ template<typename _Tp> class MatCommaInitializer_
struct CV_EXPORTS UMatData
{
enum { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24 };
DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24,
USER_ALLOCATED=32 };
UMatData(const MatAllocator* allocator);
~UMatData();

// provide atomic access to the structure
void lock();
Expand Down
8 changes: 0 additions & 8 deletions modules/core/include/opencv2/core/mat.inl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3131,14 +3131,6 @@ cols(1), allocator(0), u(0), offset(0), size(&rows)
}


inline
UMat::~UMat()
{
release();
if( step.p != step.buf )
fastFree(step.p);
}

inline
UMat& UMat::operator = (const UMat& m)
{
Expand Down
249 changes: 134 additions & 115 deletions modules/core/src/matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,146 +48,165 @@

namespace cv {

class StdMatAllocator : public MatAllocator
void MatAllocator::sync(UMatData*) const
{
public:
UMatData* allocate(int dims, const int* sizes, int type, size_t* step) const
{
size_t total = CV_ELEM_SIZE(type);
for( int i = dims-1; i >= 0; i-- )
{
if( step )
step[i] = total;
total *= sizes[i];
}
uchar* data = (uchar*)fastMalloc(total);
UMatData* u = new UMatData(this);
u->data = u->origdata = data;
u->size = total;
u->refcount = 1;
}

return u;
}
void MatAllocator::map(UMatData*, int) const
{
}

bool allocate(UMatData* u, int accessFlags) const
{
if(!u) return false;
if(u->handle != 0)
return true;
return UMat::getStdAllocator()->allocate(u, accessFlags);
}
void MatAllocator::unmap(UMatData* u) const
{
if(u->urefcount == 0 && u->refcount == 0)
deallocate(u);
}

void deallocate(UMatData* u) const
void MatAllocator::download(UMatData* u, void* dstptr,
int dims, const size_t sz[],
const size_t srcofs[], const size_t srcstep[],
const size_t dststep[]) const
{
if(!u)
return;
int isz[CV_MAX_DIM];
uchar* srcptr = u->data;
for( int i = 0; i < dims; i++ )
{
if(u)
{
fastFree(u->origdata);
delete u;
}
CV_Assert( sz[i] <= (size_t)INT_MAX );
if( sz[i] == 0 )
return;
if( srcofs )
srcptr += srcofs[i]*(i <= dims-2 ? srcstep[i] : 1);
isz[i] = (int)sz[i];
}

void map(UMatData*, int) const
{
}
Mat src(dims, isz, CV_8U, srcptr, srcstep);
Mat dst(dims, isz, CV_8U, dstptr, dststep);

const Mat* arrays[] = { &src, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t j, planesz = it.size;

void unmap(UMatData* u) const
for( j = 0; j < it.nplanes; j++, ++it )
memcpy(ptrs[1], ptrs[0], planesz);
}


void MatAllocator::upload(UMatData* u, const void* srcptr, int dims, const size_t sz[],
const size_t dstofs[], const size_t dststep[],
const size_t srcstep[]) const
{
if(!u)
return;
int isz[CV_MAX_DIM];
uchar* dstptr = u->data;
for( int i = 0; i < dims; i++ )
{
if(u->urefcount == 0)
deallocate(u);
CV_Assert( sz[i] <= (size_t)INT_MAX );
if( sz[i] == 0 )
return;
if( dstofs )
dstptr += dstofs[i]*(i <= dims-2 ? dststep[i] : 1);
isz[i] = (int)sz[i];
}

void download(UMatData* u, void* dstptr,
int dims, const size_t sz[],
Mat src(dims, isz, CV_8U, (void*)srcptr, srcstep);
Mat dst(dims, isz, CV_8U, dstptr, dststep);

const Mat* arrays[] = { &src, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t j, planesz = it.size;

for( j = 0; j < it.nplanes; j++, ++it )
memcpy(ptrs[1], ptrs[0], planesz);
}

void MatAllocator::copy(UMatData* usrc, UMatData* udst, int dims, const size_t sz[],
const size_t srcofs[], const size_t srcstep[],
const size_t dststep[]) const
const size_t dstofs[], const size_t dststep[], bool sync) const
{
if(!usrc || !udst)
return;
int isz[CV_MAX_DIM];
uchar* srcptr = usrc->data;
uchar* dstptr = udst->data;
for( int i = 0; i < dims; i++ )
{
if(!u)
return;
int isz[CV_MAX_DIM];
uchar* srcptr = u->data;
for( int i = 0; i < dims; i++ )
{
CV_Assert( sz[i] <= (size_t)INT_MAX );
if( sz[i] == 0 )
return;
if( srcofs )
srcptr += srcofs[i]*(i <= dims-2 ? srcstep[i] : 1);
isz[i] = (int)sz[i];
}
CV_Assert( sz[i] <= (size_t)INT_MAX );
if( sz[i] == 0 )
return;
if( srcofs )
srcptr += srcofs[i]*(i <= dims-2 ? srcstep[i] : 1);
if( dstofs )
dstptr += dstofs[i]*(i <= dims-2 ? dststep[i] : 1);
isz[i] = (int)sz[i];
}

Mat src(dims, isz, CV_8U, srcptr, srcstep);
Mat dst(dims, isz, CV_8U, dstptr, dststep);
Mat src(dims, isz, CV_8U, srcptr, srcstep);
Mat dst(dims, isz, CV_8U, dstptr, dststep);

const Mat* arrays[] = { &src, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t j, planesz = it.size;
const Mat* arrays[] = { &src, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t j, planesz = it.size;

for( j = 0; j < it.nplanes; j++, ++it )
memcpy(ptrs[1], ptrs[0], planesz);
}
for( j = 0; j < it.nplanes; j++, ++it )
memcpy(ptrs[1], ptrs[0], planesz);
}

void upload(UMatData* u, const void* srcptr, int dims, const size_t sz[],
const size_t dstofs[], const size_t dststep[],
const size_t srcstep[]) const
class StdMatAllocator : public MatAllocator
{
public:
UMatData* allocate(int dims, const int* sizes, int type,
void* data0, size_t* step, int /*flags*/) const
{
if(!u)
return;
int isz[CV_MAX_DIM];
uchar* dstptr = u->data;
for( int i = 0; i < dims; i++ )
size_t total = CV_ELEM_SIZE(type);
for( int i = dims-1; i >= 0; i-- )
{
CV_Assert( sz[i] <= (size_t)INT_MAX );
if( sz[i] == 0 )
return;
if( dstofs )
dstptr += dstofs[i]*(i <= dims-2 ? dststep[i] : 1);
isz[i] = (int)sz[i];
if( step )
{
if( data0 && step[i] != CV_AUTOSTEP )
{
CV_Assert(total <= step[i]);
total = step[i];
}
else
step[i] = total;
}
total *= sizes[i];
}
uchar* data = data0 ? (uchar*)data0 : (uchar*)fastMalloc(total);
UMatData* u = new UMatData(this);
u->data = u->origdata = data;
u->size = total;
u->refcount = data0 == 0;
if(data0)
u->flags |= UMatData::USER_ALLOCATED;

Mat src(dims, isz, CV_8U, (void*)srcptr, srcstep);
Mat dst(dims, isz, CV_8U, dstptr, dststep);

const Mat* arrays[] = { &src, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t j, planesz = it.size;
return u;
}

for( j = 0; j < it.nplanes; j++, ++it )
memcpy(ptrs[1], ptrs[0], planesz);
bool allocate(UMatData* u, int /*accessFlags*/) const
{
if(!u) return false;
CV_XADD(&u->urefcount, 1);
return true;
}

void copy(UMatData* usrc, UMatData* udst, int dims, const size_t sz[],
const size_t srcofs[], const size_t srcstep[],
const size_t dstofs[], const size_t dststep[], bool) const
void deallocate(UMatData* u) const
{
if(!usrc || !udst)
return;
int isz[CV_MAX_DIM];
uchar* srcptr = usrc->data;
uchar* dstptr = udst->data;
for( int i = 0; i < dims; i++ )
if(u && u->refcount == 0)
{
CV_Assert( sz[i] <= (size_t)INT_MAX );
if( sz[i] == 0 )
return;
if( srcofs )
srcptr += srcofs[i]*(i <= dims-2 ? srcstep[i] : 1);
if( dstofs )
dstptr += dstofs[i]*(i <= dims-2 ? dststep[i] : 1);
isz[i] = (int)sz[i];
if( !(u->flags & UMatData::USER_ALLOCATED) )
{
fastFree(u->origdata);
u->origdata = 0;
}
delete u;
}

Mat src(dims, isz, CV_8U, srcptr, srcstep);
Mat dst(dims, isz, CV_8U, dstptr, dststep);

const Mat* arrays[] = { &src, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t j, planesz = it.size;

for( j = 0; j < it.nplanes; j++, ++it )
memcpy(ptrs[1], ptrs[0], planesz);
}
};

Expand Down Expand Up @@ -364,13 +383,13 @@ void Mat::create(int d, const int* _sizes, int _type)
a = a0;
try
{
u = a->allocate(dims, size, _type, step.p);
u = a->allocate(dims, size, _type, 0, step.p, 0);
CV_Assert(u != 0);
}
catch(...)
{
if(a != a0)
u = a0->allocate(dims, size, _type, step.p);
u = a0->allocate(dims, size, _type, 0, step.p, 0);
CV_Assert(u != 0);
}
CV_Assert( step[dims-1] == (size_t)CV_ELEM_SIZE(flags) );
Expand Down

0 comments on commit 6da5d21

Please sign in to comment.