Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv
Commits
50d2c106
Commit
50d2c106
authored
Oct 29, 2013
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ocl: split: update tests and implementation
parent
8a4f1bbb
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
117 additions
and
123 deletions
+117
-123
cl_programcache.cpp
modules/ocl/src/cl_programcache.cpp
+1
-1
split_mat.cl
modules/ocl/src/opencl/split_mat.cl
+0
-0
safe_call.hpp
modules/ocl/src/safe_call.hpp
+1
-1
split_merge.cpp
modules/ocl/src/split_merge.cpp
+93
-55
test_split_merge.cpp
modules/ocl/test/test_split_merge.cpp
+18
-64
utility.hpp
modules/ocl/test/utility.hpp
+4
-2
No files found.
modules/ocl/src/cl_programcache.cpp
View file @
50d2c106
...
...
@@ -428,7 +428,7 @@ struct ProgramFileCache
if
(
status
!=
CL_SUCCESS
)
{
if
(
status
==
CL_BUILD_PROGRAM_FAILURE
)
if
(
status
==
CL_BUILD_PROGRAM_FAILURE
||
status
==
CL_INVALID_BUILD_OPTIONS
)
{
size_t
buildLogSize
=
0
;
openCLSafeCall
(
clGetProgramBuildInfo
(
program
,
getClDeviceID
(
ctx
),
...
...
modules/ocl/src/opencl/split_mat.cl
View file @
50d2c106
This diff is collapsed.
Click to expand it.
modules/ocl/src/safe_call.hpp
View file @
50d2c106
...
...
@@ -66,7 +66,7 @@ namespace cv
static
inline
void
___openCLSafeCall
(
int
err
,
const
char
*
file
,
const
int
line
,
const
char
*
func
=
""
)
{
if
(
CL_SUCCESS
!=
err
)
if
(
CL_SUCCESS
!=
err
)
cv
::
ocl
::
error
(
getOpenCLErrorString
(
err
),
file
,
line
,
func
);
}
}
...
...
modules/ocl/src/split_merge.cpp
View file @
50d2c106
...
...
@@ -149,90 +149,128 @@ namespace cv
mat_dst
.
create
(
size
,
CV_MAKETYPE
(
depth
,
total_channels
));
merge_vector_run
(
mat_src
,
n
,
mat_dst
);
}
static
void
split_vector_run
(
const
oclMat
&
mat_src
,
oclMat
*
mat_
dst
)
static
void
split_vector_run
(
const
oclMat
&
src
,
oclMat
*
dst
)
{
if
(
!
mat_src
.
clCxt
->
supportsFeature
(
FEATURE_CL_DOUBLE
)
&&
mat_
src
.
type
()
==
CV_64F
)
if
(
!
src
.
clCxt
->
supportsFeature
(
FEATURE_CL_DOUBLE
)
&&
src
.
type
()
==
CV_64F
)
{
CV_Error
(
CV_OpenCLDoubleNotSupported
,
"Selected device doesn't support double"
);
return
;
}
Context
*
clCxt
=
mat_src
.
clCxt
;
int
channels
=
mat_src
.
oclchannels
();
int
depth
=
mat_src
.
depth
();
Context
*
clCtx
=
src
.
clCxt
;
int
channels
=
src
.
channels
();
int
depth
=
src
.
depth
();
depth
=
(
depth
==
CV_8S
)
?
CV_8U
:
depth
;
depth
=
(
depth
==
CV_16S
)
?
CV_16U
:
depth
;
string
kernelName
=
"split_vector"
;
int
vector_lengths
[
4
][
7
]
=
{{
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
4
,
4
,
2
,
2
,
1
,
1
,
1
},
{
4
,
4
,
2
,
2
,
1
,
1
,
1
},
{
4
,
4
,
2
,
2
,
1
,
1
,
1
}
};
size_t
vector_length
=
vector_lengths
[
channels
-
1
][
mat_dst
[
0
].
depth
()];
int
max_offset_cols
=
0
;
for
(
int
i
=
0
;
i
<
channels
;
i
++
)
{
int
offset_cols
=
(
mat_dst
[
i
].
offset
/
mat_dst
[
i
].
elemSize
())
&
(
vector_length
-
1
);
if
(
max_offset_cols
<
offset_cols
)
max_offset_cols
=
offset_cols
;
}
int
cols
=
vector_length
==
1
?
divUp
(
mat_src
.
cols
,
vector_length
)
:
divUp
(
mat_src
.
cols
+
max_offset_cols
,
vector_length
);
size_t
localThreads
[
3
]
=
{
64
,
4
,
1
};
size_t
globalThreads
[
3
]
=
{
cols
,
mat_src
.
rows
,
1
};
size_t
VEC_SIZE
=
4
;
int
dst_step1
=
mat_dst
[
0
].
cols
*
mat_dst
[
0
].
elemSize
();
vector
<
pair
<
size_t
,
const
void
*>
>
args
;
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
mat_src
.
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_src
.
step
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_src
.
offset
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
mat_dst
[
0
].
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_dst
[
0
].
step
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_dst
[
0
].
offset
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
mat_dst
[
1
].
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_dst
[
1
].
step
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_dst
[
1
].
offset
));
if
(
channels
>=
3
)
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
src
.
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
src
.
step
));
int
srcOffsetXBytes
=
src
.
offset
%
src
.
step
;
int
srcOffsetY
=
src
.
offset
/
src
.
step
;
cl_int2
srcOffset
=
{{
srcOffsetXBytes
,
srcOffsetY
}};
args
.
push_back
(
make_pair
(
sizeof
(
cl_int2
),
(
void
*
)
&
srcOffset
));
bool
dst0Aligned
=
false
,
dst1Aligned
=
false
,
dst2Aligned
=
false
,
dst3Aligned
=
false
;
int
alignSize
=
dst
[
0
].
elemSize1
()
*
VEC_SIZE
;
int
alignMask
=
alignSize
-
1
;
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
dst
[
0
].
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
dst
[
0
].
step
));
int
dst0OffsetXBytes
=
dst
[
0
].
offset
%
dst
[
0
].
step
;
int
dst0OffsetY
=
dst
[
0
].
offset
/
dst
[
0
].
step
;
cl_int2
dst0Offset
=
{{
dst0OffsetXBytes
,
dst0OffsetY
}};
args
.
push_back
(
make_pair
(
sizeof
(
cl_int2
),
(
void
*
)
&
dst0Offset
));
if
((
dst0OffsetXBytes
&
alignMask
)
==
0
)
dst0Aligned
=
true
;
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
dst
[
1
].
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
dst
[
1
].
step
));
int
dst1OffsetXBytes
=
dst
[
1
].
offset
%
dst
[
1
].
step
;
int
dst1OffsetY
=
dst
[
1
].
offset
/
dst
[
1
].
step
;
cl_int2
dst1Offset
=
{{
dst1OffsetXBytes
,
dst1OffsetY
}};
args
.
push_back
(
make_pair
(
sizeof
(
cl_int2
),
(
void
*
)
&
dst1Offset
));
if
((
dst1OffsetXBytes
&
alignMask
)
==
0
)
dst1Aligned
=
true
;
// DON'T MOVE VARIABLES INTO 'IF' BODY
int
dst2OffsetXBytes
,
dst2OffsetY
;
cl_int2
dst2Offset
;
int
dst3OffsetXBytes
,
dst3OffsetY
;
cl_int2
dst3Offset
;
if
(
channels
>=
3
)
{
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
mat_dst
[
2
].
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_dst
[
2
].
step
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_dst
[
2
].
offset
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
dst
[
2
].
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
dst
[
2
].
step
));
dst2OffsetXBytes
=
dst
[
2
].
offset
%
dst
[
2
].
step
;
dst2OffsetY
=
dst
[
2
].
offset
/
dst
[
2
].
step
;
dst2Offset
.
s
[
0
]
=
dst2OffsetXBytes
;
dst2Offset
.
s
[
1
]
=
dst2OffsetY
;
args
.
push_back
(
make_pair
(
sizeof
(
cl_int2
),
(
void
*
)
&
dst2Offset
));
if
((
dst2OffsetXBytes
&
alignMask
)
==
0
)
dst2Aligned
=
true
;
}
if
(
channels
>=
4
)
if
(
channels
>=
4
)
{
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
mat_dst
[
3
].
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_dst
[
3
].
step
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_dst
[
3
].
offset
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_mem
),
(
void
*
)
&
dst
[
3
].
data
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
dst
[
3
].
step
));
dst3OffsetXBytes
=
dst
[
3
].
offset
%
dst
[
3
].
step
;
dst3OffsetY
=
dst
[
3
].
offset
/
dst
[
3
].
step
;
dst3Offset
.
s
[
0
]
=
dst3OffsetXBytes
;
dst3Offset
.
s
[
1
]
=
dst3OffsetY
;
args
.
push_back
(
make_pair
(
sizeof
(
cl_int2
),
(
void
*
)
&
dst3Offset
));
if
((
dst3OffsetXBytes
&
alignMask
)
==
0
)
dst3Aligned
=
true
;
}
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
mat_src
.
rows
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
cols
));
args
.
push_back
(
make_pair
(
sizeof
(
cl_int
),
(
void
*
)
&
dst_step1
));
openCLExecuteKernel
(
clCxt
,
&
split_mat
,
kernelName
,
globalThreads
,
localThreads
,
args
,
channels
,
depth
);
cl_int2
size
=
{{
src
.
cols
,
src
.
rows
}};
args
.
push_back
(
make_pair
(
sizeof
(
cl_int2
),
(
void
*
)
&
size
));
string
build_options
=
cv
::
format
(
"-D VEC_SIZE=%d -D DATA_DEPTH=%d -D DATA_CHAN=%d"
,
(
int
)
VEC_SIZE
,
depth
,
channels
);
if
(
dst0Aligned
)
build_options
+=
" -D DST0_ALIGNED"
;
if
(
dst1Aligned
)
build_options
+=
" -D DST1_ALIGNED"
;
if
(
dst2Aligned
)
build_options
+=
" -D DST2_ALIGNED"
;
if
(
dst3Aligned
)
build_options
+=
" -D DST3_ALIGNED"
;
const
DeviceInfo
&
devInfo
=
clCtx
->
getDeviceInfo
();
// TODO Workaround for issues. Need to investigate a problem.
if
(
channels
==
2
&&
devInfo
.
deviceType
==
CVCL_DEVICE_TYPE_CPU
&&
devInfo
.
platform
->
platformVendor
.
find
(
"Intel"
)
!=
std
::
string
::
npos
&&
(
devInfo
.
deviceVersion
.
find
(
"Build 56860"
)
!=
std
::
string
::
npos
||
devInfo
.
deviceVersion
.
find
(
"Build 76921"
)
!=
std
::
string
::
npos
))
build_options
+=
" -D BYPASS_VSTORE=true"
;
size_t
globalThreads
[
3
]
=
{
divUp
(
src
.
cols
,
VEC_SIZE
),
src
.
rows
,
1
};
openCLExecuteKernel
(
clCtx
,
&
split_mat
,
kernelName
,
globalThreads
,
NULL
,
args
,
-
1
,
-
1
,
build_options
.
c_str
());
}
static
void
split
(
const
oclMat
&
mat_src
,
oclMat
*
mat_dst
)
{
CV_Assert
(
mat_dst
);
int
depth
=
mat_src
.
depth
();
int
num_channels
=
mat_src
.
ocl
channels
();
int
num_channels
=
mat_src
.
channels
();
Size
size
=
mat_src
.
size
();
if
(
num_channels
==
1
)
if
(
num_channels
==
1
)
{
mat_src
.
copyTo
(
mat_dst
[
0
]);
return
;
}
int
i
;
for
(
i
=
0
;
i
<
num_channels
;
i
++
)
for
(
int
i
=
0
;
i
<
mat_src
.
oclchannels
();
i
++
)
mat_dst
[
i
].
create
(
size
,
CV_MAKETYPE
(
depth
,
1
));
split_vector_run
(
mat_src
,
mat_dst
);
...
...
@@ -256,7 +294,7 @@ void cv::ocl::split(const oclMat &src, oclMat *dst)
}
void
cv
::
ocl
::
split
(
const
oclMat
&
src
,
vector
<
oclMat
>
&
dst
)
{
dst
.
resize
(
src
.
oclchannels
());
dst
.
resize
(
src
.
oclchannels
());
// TODO Why oclchannels?
if
(
src
.
oclchannels
()
>
0
)
split_merge
::
split
(
src
,
&
dst
[
0
]);
}
modules/ocl/test/test_split_merge.cpp
View file @
50d2c106
...
...
@@ -158,81 +158,32 @@ PARAM_TEST_CASE(SplitTestBase, MatType, int, bool)
int
channels
;
bool
use_roi
;
//src mat
cv
::
Mat
mat
;
//dstmat
cv
::
Mat
dst
[
MAX_CHANNELS
];
// set up roi
int
roicols
,
roirows
;
int
srcx
,
srcy
;
int
dstx
[
MAX_CHANNELS
];
int
dsty
[
MAX_CHANNELS
];
//src mat with roi
cv
::
Mat
mat_roi
;
//dst mat with roi
cv
::
Mat
dst_roi
[
MAX_CHANNELS
];
cv
::
Mat
src
,
src_roi
;
cv
::
Mat
dst
[
MAX_CHANNELS
],
dst_roi
[
MAX_CHANNELS
];
//ocl dst mat for testing
cv
::
ocl
::
oclMat
gdst_whole
[
MAX_CHANNELS
];
//ocl mat with roi
cv
::
ocl
::
oclMat
gmat
;
cv
::
ocl
::
oclMat
gdst
[
MAX_CHANNELS
];
cv
::
ocl
::
oclMat
gsrc_whole
,
gsrc_roi
;
cv
::
ocl
::
oclMat
gdst_whole
[
MAX_CHANNELS
],
gdst_roi
[
MAX_CHANNELS
];
virtual
void
SetUp
()
{
type
=
GET_PARAM
(
0
);
channels
=
GET_PARAM
(
1
);
use_roi
=
GET_PARAM
(
2
);
cv
::
Size
size
(
MWIDTH
,
MHEIGHT
);
mat
=
randomMat
(
size
,
CV_MAKETYPE
(
type
,
channels
),
5
,
16
,
false
);
for
(
int
i
=
0
;
i
<
channels
;
++
i
)
dst
[
i
]
=
randomMat
(
size
,
CV_MAKETYPE
(
type
,
1
),
5
,
16
,
false
);
}
}
void
random_roi
()
{
if
(
use_roi
)
{
//randomize ROI
roicols
=
rng
.
uniform
(
1
,
mat
.
cols
);
roirows
=
rng
.
uniform
(
1
,
mat
.
rows
);
srcx
=
rng
.
uniform
(
0
,
mat
.
cols
-
roicols
);
srcy
=
rng
.
uniform
(
0
,
mat
.
rows
-
roirows
);
for
(
int
i
=
0
;
i
<
channels
;
++
i
)
{
dstx
[
i
]
=
rng
.
uniform
(
0
,
dst
[
i
].
cols
-
roicols
);
dsty
[
i
]
=
rng
.
uniform
(
0
,
dst
[
i
].
rows
-
roirows
);
}
}
else
{
roicols
=
mat
.
cols
;
roirows
=
mat
.
rows
;
srcx
=
srcy
=
0
;
for
(
int
i
=
0
;
i
<
channels
;
++
i
)
dstx
[
i
]
=
dsty
[
i
]
=
0
;
}
mat_roi
=
mat
(
Rect
(
srcx
,
srcy
,
roicols
,
roirows
));
for
(
int
i
=
0
;
i
<
channels
;
++
i
)
dst_roi
[
i
]
=
dst
[
i
](
Rect
(
dstx
[
i
],
dsty
[
i
],
roicols
,
roirows
));
Size
roiSize
=
randomSize
(
1
,
MAX_VALUE
);
Border
srcBorder
=
randomBorder
(
0
,
use_roi
?
MAX_VALUE
:
0
);
randomSubMat
(
src
,
src_roi
,
roiSize
,
srcBorder
,
CV_MAKETYPE
(
type
,
channels
),
0
,
256
);
generateOclMat
(
gsrc_whole
,
gsrc_roi
,
src
,
roiSize
,
srcBorder
);
for
(
int
i
=
0
;
i
<
channels
;
++
i
)
{
gdst_whole
[
i
]
=
dst
[
i
];
gdst
[
i
]
=
gdst_whole
[
i
](
Rect
(
dstx
[
i
],
dsty
[
i
],
roicols
,
roirows
));
Border
dstBorder
=
randomBorder
(
0
,
use_roi
?
MAX_VALUE
:
0
);
randomSubMat
(
dst
[
i
],
dst_roi
[
i
],
roiSize
,
dstBorder
,
CV_MAKETYPE
(
type
,
1
),
5
,
16
);
generateOclMat
(
gdst_whole
[
i
],
gdst_roi
[
i
],
dst
[
i
],
roiSize
,
dstBorder
);
}
gmat
=
mat_roi
;
}
};
...
...
@@ -244,11 +195,14 @@ OCL_TEST_P(Split, Accuracy)
{
random_roi
();
cv
::
split
(
mat
_roi
,
dst_roi
);
cv
::
ocl
::
split
(
g
mat
,
gdst
);
cv
::
split
(
src
_roi
,
dst_roi
);
cv
::
ocl
::
split
(
g
src_roi
,
gdst_roi
);
for
(
int
i
=
0
;
i
<
channels
;
++
i
)
EXPECT_MAT_NEAR
(
dst
[
i
],
Mat
(
gdst_whole
[
i
]),
0.0
);
{
EXPECT_MAT_NEAR
(
dst
[
i
],
gdst_whole
[
i
],
0.0
);
EXPECT_MAT_NEAR
(
dst_roi
[
i
],
gdst_roi
[
i
],
0.0
);
}
}
}
...
...
modules/ocl/test/utility.hpp
View file @
50d2c106
...
...
@@ -88,14 +88,16 @@ inline double checkNormRelative(const Mat &m1, const Mat &m2)
{ \
ASSERT_EQ(mat1.type(), mat2.type()); \
ASSERT_EQ(mat1.size(), mat2.size()); \
EXPECT_LE(checkNorm(cv::Mat(mat1), cv::Mat(mat2)), eps); \
EXPECT_LE(checkNorm(cv::Mat(mat1), cv::Mat(mat2)), eps) \
<< cv::format("Size: %d x %d", mat1.cols, mat1.rows) << std::endl; \
}
#define EXPECT_MAT_NEAR_RELATIVE(mat1, mat2, eps) \
{ \
ASSERT_EQ(mat1.type(), mat2.type()); \
ASSERT_EQ(mat1.size(), mat2.size()); \
EXPECT_LE(checkNormRelative(cv::Mat(mat1), cv::Mat(mat2)), eps); \
EXPECT_LE(checkNormRelative(cv::Mat(mat1), cv::Mat(mat2)), eps) \
<< cv::format("Size: %d x %d", mat1.cols, mat1.rows) << std::endl; \
}
#define EXPECT_MAT_SIMILAR(mat1, mat2, eps) \
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment