mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
core: rework code locality
- to reduce binaries size of FFmpeg Windows wrapper - MinGW linker doesn't support -ffunction-sections (used for FFmpeg Windows wrapper) - move code to improve locality with its used dependencies - move UMat::dot() to matmul.dispatch.cpp (Mat::dot() is already there) - move UMat::inv() to lapack.cpp - move UMat::mul() to arithm.cpp - move UMat:eye() to matrix_operations.cpp (near setIdentity() implementation) - move normalize(): convert_scale.cpp => norm.cpp - move convertAndUnrollScalar(): arithm.cpp => copy.cpp - move scalarToRawData(): array.cpp => copy.cpp - move transpose(): matrix_operations.cpp => matrix_transform.cpp - move flip(), rotate(): copy.cpp => matrix_transform.cpp (rotate90 uses flip and transpose) - add 'OPENCV_CORE_EXCLUDE_C_API' CMake variable to exclude compilation of C-API functions from the core module - matrix_wrap.cpp: add compile-time checks for CUDA/OpenGL calls - the steps above allow to reduce FFmpeg wrapper size for ~1.5Mb (initial size of OpenCV part is about 3Mb)
This commit is contained in:
@@ -226,6 +226,23 @@ void cv::setIdentity( InputOutputArray _m, const Scalar& s )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace cv {
|
||||
|
||||
UMat UMat::eye(int rows, int cols, int type)
|
||||
{
|
||||
return UMat::eye(Size(cols, rows), type);
|
||||
}
|
||||
|
||||
UMat UMat::eye(Size size, int type)
|
||||
{
|
||||
UMat m(size, type);
|
||||
setIdentity(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
//////////////////////////////////////////// trace ///////////////////////////////////////////
|
||||
|
||||
cv::Scalar cv::trace( InputArray _m )
|
||||
@@ -260,285 +277,6 @@ cv::Scalar cv::trace( InputArray _m )
|
||||
return cv::sum(m.diag());
|
||||
}
|
||||
|
||||
////////////////////////////////////// transpose /////////////////////////////////////////
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
template<typename T> static void
|
||||
transpose_( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size sz )
|
||||
{
|
||||
int i=0, j, m = sz.width, n = sz.height;
|
||||
|
||||
#if CV_ENABLE_UNROLLED
|
||||
for(; i <= m - 4; i += 4 )
|
||||
{
|
||||
T* d0 = (T*)(dst + dstep*i);
|
||||
T* d1 = (T*)(dst + dstep*(i+1));
|
||||
T* d2 = (T*)(dst + dstep*(i+2));
|
||||
T* d3 = (T*)(dst + dstep*(i+3));
|
||||
|
||||
for( j = 0; j <= n - 4; j += 4 )
|
||||
{
|
||||
const T* s0 = (const T*)(src + i*sizeof(T) + sstep*j);
|
||||
const T* s1 = (const T*)(src + i*sizeof(T) + sstep*(j+1));
|
||||
const T* s2 = (const T*)(src + i*sizeof(T) + sstep*(j+2));
|
||||
const T* s3 = (const T*)(src + i*sizeof(T) + sstep*(j+3));
|
||||
|
||||
d0[j] = s0[0]; d0[j+1] = s1[0]; d0[j+2] = s2[0]; d0[j+3] = s3[0];
|
||||
d1[j] = s0[1]; d1[j+1] = s1[1]; d1[j+2] = s2[1]; d1[j+3] = s3[1];
|
||||
d2[j] = s0[2]; d2[j+1] = s1[2]; d2[j+2] = s2[2]; d2[j+3] = s3[2];
|
||||
d3[j] = s0[3]; d3[j+1] = s1[3]; d3[j+2] = s2[3]; d3[j+3] = s3[3];
|
||||
}
|
||||
|
||||
for( ; j < n; j++ )
|
||||
{
|
||||
const T* s0 = (const T*)(src + i*sizeof(T) + j*sstep);
|
||||
d0[j] = s0[0]; d1[j] = s0[1]; d2[j] = s0[2]; d3[j] = s0[3];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for( ; i < m; i++ )
|
||||
{
|
||||
T* d0 = (T*)(dst + dstep*i);
|
||||
j = 0;
|
||||
#if CV_ENABLE_UNROLLED
|
||||
for(; j <= n - 4; j += 4 )
|
||||
{
|
||||
const T* s0 = (const T*)(src + i*sizeof(T) + sstep*j);
|
||||
const T* s1 = (const T*)(src + i*sizeof(T) + sstep*(j+1));
|
||||
const T* s2 = (const T*)(src + i*sizeof(T) + sstep*(j+2));
|
||||
const T* s3 = (const T*)(src + i*sizeof(T) + sstep*(j+3));
|
||||
|
||||
d0[j] = s0[0]; d0[j+1] = s1[0]; d0[j+2] = s2[0]; d0[j+3] = s3[0];
|
||||
}
|
||||
#endif
|
||||
for( ; j < n; j++ )
|
||||
{
|
||||
const T* s0 = (const T*)(src + i*sizeof(T) + j*sstep);
|
||||
d0[j] = s0[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> static void
|
||||
transposeI_( uchar* data, size_t step, int n )
|
||||
{
|
||||
for( int i = 0; i < n; i++ )
|
||||
{
|
||||
T* row = (T*)(data + step*i);
|
||||
uchar* data1 = data + i*sizeof(T);
|
||||
for( int j = i+1; j < n; j++ )
|
||||
std::swap( row[j], *(T*)(data1 + step*j) );
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*TransposeFunc)( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size sz );
|
||||
typedef void (*TransposeInplaceFunc)( uchar* data, size_t step, int n );
|
||||
|
||||
#define DEF_TRANSPOSE_FUNC(suffix, type) \
|
||||
static void transpose_##suffix( const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size sz ) \
|
||||
{ transpose_<type>(src, sstep, dst, dstep, sz); } \
|
||||
\
|
||||
static void transposeI_##suffix( uchar* data, size_t step, int n ) \
|
||||
{ transposeI_<type>(data, step, n); }
|
||||
|
||||
DEF_TRANSPOSE_FUNC(8u, uchar)
|
||||
DEF_TRANSPOSE_FUNC(16u, ushort)
|
||||
DEF_TRANSPOSE_FUNC(8uC3, Vec3b)
|
||||
DEF_TRANSPOSE_FUNC(32s, int)
|
||||
DEF_TRANSPOSE_FUNC(16uC3, Vec3s)
|
||||
DEF_TRANSPOSE_FUNC(32sC2, Vec2i)
|
||||
DEF_TRANSPOSE_FUNC(32sC3, Vec3i)
|
||||
DEF_TRANSPOSE_FUNC(32sC4, Vec4i)
|
||||
DEF_TRANSPOSE_FUNC(32sC6, Vec6i)
|
||||
DEF_TRANSPOSE_FUNC(32sC8, Vec8i)
|
||||
|
||||
static TransposeFunc transposeTab[] =
|
||||
{
|
||||
0, transpose_8u, transpose_16u, transpose_8uC3, transpose_32s, 0, transpose_16uC3, 0,
|
||||
transpose_32sC2, 0, 0, 0, transpose_32sC3, 0, 0, 0, transpose_32sC4,
|
||||
0, 0, 0, 0, 0, 0, 0, transpose_32sC6, 0, 0, 0, 0, 0, 0, 0, transpose_32sC8
|
||||
};
|
||||
|
||||
static TransposeInplaceFunc transposeInplaceTab[] =
|
||||
{
|
||||
0, transposeI_8u, transposeI_16u, transposeI_8uC3, transposeI_32s, 0, transposeI_16uC3, 0,
|
||||
transposeI_32sC2, 0, 0, 0, transposeI_32sC3, 0, 0, 0, transposeI_32sC4,
|
||||
0, 0, 0, 0, 0, 0, 0, transposeI_32sC6, 0, 0, 0, 0, 0, 0, 0, transposeI_32sC8
|
||||
};
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
static bool ocl_transpose( InputArray _src, OutputArray _dst )
|
||||
{
|
||||
const ocl::Device & dev = ocl::Device::getDefault();
|
||||
const int TILE_DIM = 32, BLOCK_ROWS = 8;
|
||||
int type = _src.type(), cn = CV_MAT_CN(type), depth = CV_MAT_DEPTH(type),
|
||||
rowsPerWI = dev.isIntel() ? 4 : 1;
|
||||
|
||||
UMat src = _src.getUMat();
|
||||
_dst.create(src.cols, src.rows, type);
|
||||
UMat dst = _dst.getUMat();
|
||||
|
||||
String kernelName("transpose");
|
||||
bool inplace = dst.u == src.u;
|
||||
|
||||
if (inplace)
|
||||
{
|
||||
CV_Assert(dst.cols == dst.rows);
|
||||
kernelName += "_inplace";
|
||||
}
|
||||
else
|
||||
{
|
||||
// check required local memory size
|
||||
size_t required_local_memory = (size_t) TILE_DIM*(TILE_DIM+1)*CV_ELEM_SIZE(type);
|
||||
if (required_local_memory > ocl::Device::getDefault().localMemSize())
|
||||
return false;
|
||||
}
|
||||
|
||||
ocl::Kernel k(kernelName.c_str(), ocl::core::transpose_oclsrc,
|
||||
format("-D T=%s -D T1=%s -D cn=%d -D TILE_DIM=%d -D BLOCK_ROWS=%d -D rowsPerWI=%d%s",
|
||||
ocl::memopTypeToStr(type), ocl::memopTypeToStr(depth),
|
||||
cn, TILE_DIM, BLOCK_ROWS, rowsPerWI, inplace ? " -D INPLACE" : ""));
|
||||
if (k.empty())
|
||||
return false;
|
||||
|
||||
if (inplace)
|
||||
k.args(ocl::KernelArg::ReadWriteNoSize(dst), dst.rows);
|
||||
else
|
||||
k.args(ocl::KernelArg::ReadOnly(src),
|
||||
ocl::KernelArg::WriteOnlyNoSize(dst));
|
||||
|
||||
size_t localsize[2] = { TILE_DIM, BLOCK_ROWS };
|
||||
size_t globalsize[2] = { (size_t)src.cols, inplace ? ((size_t)src.rows + rowsPerWI - 1) / rowsPerWI : (divUp((size_t)src.rows, TILE_DIM) * BLOCK_ROWS) };
|
||||
|
||||
if (inplace && dev.isIntel())
|
||||
{
|
||||
localsize[0] = 16;
|
||||
localsize[1] = dev.maxWorkGroupSize() / localsize[0];
|
||||
}
|
||||
|
||||
return k.run(2, globalsize, localsize, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
static bool ipp_transpose( Mat &src, Mat &dst )
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
int type = src.type();
|
||||
typedef IppStatus (CV_STDCALL * IppiTranspose)(const void * pSrc, int srcStep, void * pDst, int dstStep, IppiSize roiSize);
|
||||
typedef IppStatus (CV_STDCALL * IppiTransposeI)(const void * pSrcDst, int srcDstStep, IppiSize roiSize);
|
||||
IppiTranspose ippiTranspose = 0;
|
||||
IppiTransposeI ippiTranspose_I = 0;
|
||||
|
||||
if (dst.data == src.data && dst.cols == dst.rows)
|
||||
{
|
||||
CV_SUPPRESS_DEPRECATED_START
|
||||
ippiTranspose_I =
|
||||
type == CV_8UC1 ? (IppiTransposeI)ippiTranspose_8u_C1IR :
|
||||
type == CV_8UC3 ? (IppiTransposeI)ippiTranspose_8u_C3IR :
|
||||
type == CV_8UC4 ? (IppiTransposeI)ippiTranspose_8u_C4IR :
|
||||
type == CV_16UC1 ? (IppiTransposeI)ippiTranspose_16u_C1IR :
|
||||
type == CV_16UC3 ? (IppiTransposeI)ippiTranspose_16u_C3IR :
|
||||
type == CV_16UC4 ? (IppiTransposeI)ippiTranspose_16u_C4IR :
|
||||
type == CV_16SC1 ? (IppiTransposeI)ippiTranspose_16s_C1IR :
|
||||
type == CV_16SC3 ? (IppiTransposeI)ippiTranspose_16s_C3IR :
|
||||
type == CV_16SC4 ? (IppiTransposeI)ippiTranspose_16s_C4IR :
|
||||
type == CV_32SC1 ? (IppiTransposeI)ippiTranspose_32s_C1IR :
|
||||
type == CV_32SC3 ? (IppiTransposeI)ippiTranspose_32s_C3IR :
|
||||
type == CV_32SC4 ? (IppiTransposeI)ippiTranspose_32s_C4IR :
|
||||
type == CV_32FC1 ? (IppiTransposeI)ippiTranspose_32f_C1IR :
|
||||
type == CV_32FC3 ? (IppiTransposeI)ippiTranspose_32f_C3IR :
|
||||
type == CV_32FC4 ? (IppiTransposeI)ippiTranspose_32f_C4IR : 0;
|
||||
CV_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
else
|
||||
{
|
||||
ippiTranspose =
|
||||
type == CV_8UC1 ? (IppiTranspose)ippiTranspose_8u_C1R :
|
||||
type == CV_8UC3 ? (IppiTranspose)ippiTranspose_8u_C3R :
|
||||
type == CV_8UC4 ? (IppiTranspose)ippiTranspose_8u_C4R :
|
||||
type == CV_16UC1 ? (IppiTranspose)ippiTranspose_16u_C1R :
|
||||
type == CV_16UC3 ? (IppiTranspose)ippiTranspose_16u_C3R :
|
||||
type == CV_16UC4 ? (IppiTranspose)ippiTranspose_16u_C4R :
|
||||
type == CV_16SC1 ? (IppiTranspose)ippiTranspose_16s_C1R :
|
||||
type == CV_16SC3 ? (IppiTranspose)ippiTranspose_16s_C3R :
|
||||
type == CV_16SC4 ? (IppiTranspose)ippiTranspose_16s_C4R :
|
||||
type == CV_32SC1 ? (IppiTranspose)ippiTranspose_32s_C1R :
|
||||
type == CV_32SC3 ? (IppiTranspose)ippiTranspose_32s_C3R :
|
||||
type == CV_32SC4 ? (IppiTranspose)ippiTranspose_32s_C4R :
|
||||
type == CV_32FC1 ? (IppiTranspose)ippiTranspose_32f_C1R :
|
||||
type == CV_32FC3 ? (IppiTranspose)ippiTranspose_32f_C3R :
|
||||
type == CV_32FC4 ? (IppiTranspose)ippiTranspose_32f_C4R : 0;
|
||||
}
|
||||
|
||||
IppiSize roiSize = { src.cols, src.rows };
|
||||
if (ippiTranspose != 0)
|
||||
{
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiTranspose, src.ptr(), (int)src.step, dst.ptr(), (int)dst.step, roiSize) >= 0)
|
||||
return true;
|
||||
}
|
||||
else if (ippiTranspose_I != 0)
|
||||
{
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiTranspose_I, dst.ptr(), (int)dst.step, roiSize) >= 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void cv::transpose( InputArray _src, OutputArray _dst )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
int type = _src.type(), esz = CV_ELEM_SIZE(type);
|
||||
CV_Assert( _src.dims() <= 2 && esz <= 32 );
|
||||
|
||||
CV_OCL_RUN(_dst.isUMat(),
|
||||
ocl_transpose(_src, _dst))
|
||||
|
||||
Mat src = _src.getMat();
|
||||
if( src.empty() )
|
||||
{
|
||||
_dst.release();
|
||||
return;
|
||||
}
|
||||
|
||||
_dst.create(src.cols, src.rows, src.type());
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
// handle the case of single-column/single-row matrices, stored in STL vectors.
|
||||
if( src.rows != dst.cols || src.cols != dst.rows )
|
||||
{
|
||||
CV_Assert( src.size() == dst.size() && (src.cols == 1 || src.rows == 1) );
|
||||
src.copyTo(dst);
|
||||
return;
|
||||
}
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_transpose(src, dst))
|
||||
|
||||
if( dst.data == src.data )
|
||||
{
|
||||
TransposeInplaceFunc func = transposeInplaceTab[esz];
|
||||
CV_Assert( func != 0 );
|
||||
CV_Assert( dst.cols == dst.rows );
|
||||
func( dst.ptr(), dst.step, dst.rows );
|
||||
}
|
||||
else
|
||||
{
|
||||
TransposeFunc func = transposeTab[esz];
|
||||
CV_Assert( func != 0 );
|
||||
func( src.ptr(), src.step, dst.ptr(), dst.step, src.size() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////// completeSymm /////////////////////////////////////////
|
||||
|
||||
|
||||
Reference in New Issue
Block a user