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
17ca7f95
Commit
17ca7f95
authored
Dec 12, 2013
by
Alexander Alekhin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ocl: add support for initialization from user-provided OpenCL handles
parent
658282fc
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
379 additions
and
171 deletions
+379
-171
CMakeLists.txt
modules/ocl/CMakeLists.txt
+3
-0
structures_and_utility_functions.rst
modules/ocl/doc/structures_and_utility_functions.rst
+15
-1
ocl.hpp
modules/ocl/include/opencv2/ocl/ocl.hpp
+6
-0
cl_context.cpp
modules/ocl/src/cl_context.cpp
+270
-169
test_api.cpp
modules/ocl/test/test_api.cpp
+85
-1
No files found.
modules/ocl/CMakeLists.txt
View file @
17ca7f95
...
...
@@ -5,4 +5,7 @@ endif()
set
(
the_description
"OpenCL-accelerated Computer Vision"
)
ocv_define_module
(
ocl opencv_core opencv_imgproc opencv_features2d opencv_objdetect opencv_video opencv_calib3d opencv_ml
"
${
OPENCL_LIBRARIES
}
"
)
if
(
TARGET opencv_test_ocl
)
target_link_libraries
(
opencv_test_ocl
"
${
OPENCL_LIBRARIES
}
"
)
endif
()
ocv_warnings_disable
(
CMAKE_CXX_FLAGS -Wshadow
)
modules/ocl/doc/structures_and_utility_functions.rst
View file @
17ca7f95
...
...
@@ -25,12 +25,26 @@ Returns the list of devices
ocl::setDevice
--------------
Returns void
Initialize OpenCL computation context
.. ocv:function:: void ocl::setDevice( const DeviceInfo* info )
:param info: device info
ocl::initializeContext
--------------------------------
Alternative way to initialize OpenCL computation context.
.. ocv:function:: void ocl::initializeContext(void* pClPlatform, void* pClContext, void* pClDevice)
:param pClPlatform: selected ``platform_id`` (via pointer, parameter type is ``cl_platform_id*``)
:param pClContext: selected ``cl_context`` (via pointer, parameter type is ``cl_context*``)
:param pClDevice: selected ``cl_device_id`` (via pointer, parameter type is ``cl_device_id*``)
This function can be used for context initialization with D3D/OpenGL interoperability.
ocl::setBinaryPath
------------------
Returns void
...
...
modules/ocl/include/opencv2/ocl/ocl.hpp
View file @
17ca7f95
...
...
@@ -118,6 +118,7 @@ namespace cv
const
PlatformInfo
*
platform
;
DeviceInfo
();
~
DeviceInfo
();
};
struct
PlatformInfo
...
...
@@ -136,6 +137,7 @@ namespace cv
std
::
vector
<
const
DeviceInfo
*>
devices
;
PlatformInfo
();
~
PlatformInfo
();
};
//////////////////////////////// Initialization & Info ////////////////////////
...
...
@@ -151,6 +153,10 @@ namespace cv
// set device you want to use
CV_EXPORTS
void
setDevice
(
const
DeviceInfo
*
info
);
// Initialize from OpenCL handles directly.
// Argument types is (pointers): cl_platform_id*, cl_context*, cl_device_id*
CV_EXPORTS
void
initializeContext
(
void
*
pClPlatform
,
void
*
pClContext
,
void
*
pClDevice
);
//////////////////////////////// Error handling ////////////////////////
CV_EXPORTS
void
error
(
const
char
*
error_string
,
const
char
*
file
,
const
int
line
,
const
char
*
func
);
...
...
modules/ocl/src/cl_context.cpp
View file @
17ca7f95
...
...
@@ -57,6 +57,8 @@
namespace
cv
{
namespace
ocl
{
using
namespace
cl_utils
;
#if defined(WIN32)
static
bool
__termination
=
false
;
#endif
...
...
@@ -75,36 +77,10 @@ cv::Mutex& getInitializationMutex()
return
__module
.
initializationMutex
;
}
struct
PlatformInfoImpl
{
cl_platform_id
platform_id
;
std
::
vector
<
int
>
deviceIDs
;
PlatformInfo
info
;
PlatformInfoImpl
()
:
platform_id
(
NULL
)
{
}
};
struct
DeviceInfoImpl
static
cv
::
Mutex
&
getCurrentContextMutex
()
{
cl_platform_id
platform_id
;
cl_device_id
device_id
;
DeviceInfo
info
;
DeviceInfoImpl
()
:
platform_id
(
NULL
),
device_id
(
NULL
)
{
}
};
static
std
::
vector
<
PlatformInfoImpl
>
global_platforms
;
static
std
::
vector
<
DeviceInfoImpl
>
global_devices
;
return
__module
.
currentContextMutex
;
}
static
bool
parseOpenCLVersion
(
const
std
::
string
&
versionStr
,
int
&
major
,
int
&
minor
)
{
...
...
@@ -135,6 +111,141 @@ static bool parseOpenCLVersion(const std::string& versionStr, int& major, int& m
return
true
;
}
struct
PlatformInfoImpl
:
public
PlatformInfo
{
cl_platform_id
platform_id
;
std
::
vector
<
int
>
deviceIDs
;
PlatformInfoImpl
()
:
platform_id
(
NULL
)
{
}
void
init
(
int
id
,
cl_platform_id
platform
)
{
CV_Assert
(
platform_id
==
NULL
);
this
->
_id
=
id
;
platform_id
=
platform
;
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_PROFILE
,
this
->
platformProfile
));
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_VERSION
,
this
->
platformVersion
));
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_NAME
,
this
->
platformName
));
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_VENDOR
,
this
->
platformVendor
));
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_EXTENSIONS
,
this
->
platformExtensons
));
parseOpenCLVersion
(
this
->
platformVersion
,
this
->
platformVersionMajor
,
this
->
platformVersionMinor
);
}
};
struct
DeviceInfoImpl
:
public
DeviceInfo
{
cl_platform_id
platform_id
;
cl_device_id
device_id
;
DeviceInfoImpl
()
:
platform_id
(
NULL
),
device_id
(
NULL
)
{
}
void
init
(
int
id
,
PlatformInfoImpl
&
platformInfoImpl
,
cl_device_id
device
)
{
CV_Assert
(
device_id
==
NULL
);
this
->
_id
=
id
;
platform_id
=
platformInfoImpl
.
platform_id
;
device_id
=
device
;
this
->
platform
=
&
platformInfoImpl
;
cl_device_type
type
=
cl_device_type
(
-
1
);
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_TYPE
,
type
));
this
->
deviceType
=
DeviceType
(
type
);
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_PROFILE
,
this
->
deviceProfile
));
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_VERSION
,
this
->
deviceVersion
));
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_NAME
,
this
->
deviceName
));
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_VENDOR
,
this
->
deviceVendor
));
cl_uint
vendorID
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_VENDOR_ID
,
vendorID
));
this
->
deviceVendorId
=
vendorID
;
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DRIVER_VERSION
,
this
->
deviceDriverVersion
));
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_EXTENSIONS
,
this
->
deviceExtensions
));
parseOpenCLVersion
(
this
->
deviceVersion
,
this
->
deviceVersionMajor
,
this
->
deviceVersionMinor
);
size_t
maxWorkGroupSize
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_MAX_WORK_GROUP_SIZE
,
maxWorkGroupSize
));
this
->
maxWorkGroupSize
=
maxWorkGroupSize
;
cl_uint
maxDimensions
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
,
maxDimensions
));
std
::
vector
<
size_t
>
maxWorkItemSizes
(
maxDimensions
);
openCLSafeCall
(
clGetDeviceInfo
(
device
,
CL_DEVICE_MAX_WORK_ITEM_SIZES
,
sizeof
(
size_t
)
*
maxDimensions
,
(
void
*
)
&
maxWorkItemSizes
[
0
],
0
));
this
->
maxWorkItemSizes
=
maxWorkItemSizes
;
cl_uint
maxComputeUnits
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_MAX_COMPUTE_UNITS
,
maxComputeUnits
));
this
->
maxComputeUnits
=
maxComputeUnits
;
cl_ulong
localMemorySize
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_LOCAL_MEM_SIZE
,
localMemorySize
));
this
->
localMemorySize
=
(
size_t
)
localMemorySize
;
cl_ulong
maxMemAllocSize
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_MAX_MEM_ALLOC_SIZE
,
maxMemAllocSize
));
this
->
maxMemAllocSize
=
(
size_t
)
maxMemAllocSize
;
cl_bool
unifiedMemory
=
false
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_HOST_UNIFIED_MEMORY
,
unifiedMemory
));
this
->
isUnifiedMemory
=
unifiedMemory
!=
0
;
//initialize extra options for compilation. Currently only fp64 is included.
//Assume 4KB is enough to store all possible extensions.
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_EXTENSIONS
,
this
->
deviceExtensions
));
size_t
fp64_khr
=
this
->
deviceExtensions
.
find
(
"cl_khr_fp64"
);
if
(
fp64_khr
!=
std
::
string
::
npos
)
{
this
->
compilationExtraOptions
+=
"-D DOUBLE_SUPPORT"
;
this
->
haveDoubleSupport
=
true
;
}
else
{
this
->
haveDoubleSupport
=
false
;
}
size_t
intel_platform
=
platformInfoImpl
.
platformVendor
.
find
(
"Intel"
);
if
(
intel_platform
!=
std
::
string
::
npos
)
{
this
->
compilationExtraOptions
+=
" -D INTEL_DEVICE"
;
this
->
isIntelDevice
=
true
;
}
else
{
this
->
isIntelDevice
=
false
;
}
if
(
id
<
0
)
{
#ifdef CL_VERSION_1_2
if
(
this
->
deviceVersionMajor
>
1
||
(
this
->
deviceVersionMajor
==
1
&&
this
->
deviceVersionMinor
>=
2
))
{
::
clRetainDevice
(
device
);
}
#endif
}
}
};
static
std
::
vector
<
PlatformInfoImpl
>
global_platforms
;
static
std
::
vector
<
DeviceInfoImpl
>
global_devices
;
static
void
split
(
const
std
::
string
&
s
,
char
delim
,
std
::
vector
<
std
::
string
>
&
elems
)
{
std
::
stringstream
ss
(
s
);
std
::
string
item
;
...
...
@@ -333,8 +444,6 @@ not_found:
static
bool
__initialized
=
false
;
static
int
initializeOpenCLDevices
()
{
using
namespace
cl_utils
;
assert
(
!
__initialized
);
__initialized
=
true
;
...
...
@@ -355,19 +464,9 @@ static int initializeOpenCLDevices()
for
(
size_t
i
=
0
;
i
<
platforms
.
size
();
++
i
)
{
PlatformInfoImpl
&
platformInfo
=
global_platforms
[
i
];
platformInfo
.
info
.
_id
=
i
;
cl_platform_id
platform
=
platforms
[
i
];
platformInfo
.
platform_id
=
platform
;
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_PROFILE
,
platformInfo
.
info
.
platformProfile
));
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_VERSION
,
platformInfo
.
info
.
platformVersion
));
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_NAME
,
platformInfo
.
info
.
platformName
));
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_VENDOR
,
platformInfo
.
info
.
platformVendor
));
openCLSafeCall
(
getStringInfo
(
clGetPlatformInfo
,
platform
,
CL_PLATFORM_EXTENSIONS
,
platformInfo
.
info
.
platformExtensons
));
parseOpenCLVersion
(
platformInfo
.
info
.
platformVersion
,
platformInfo
.
info
.
platformVersionMajor
,
platformInfo
.
info
.
platformVersionMinor
);
platformInfo
.
init
(
i
,
platform
);
std
::
vector
<
cl_device_id
>
devices
;
cl_int
status
=
getDevices
(
platform
,
CL_DEVICE_TYPE_ALL
,
devices
);
...
...
@@ -379,89 +478,15 @@ static int initializeOpenCLDevices()
int
baseIndx
=
global_devices
.
size
();
global_devices
.
resize
(
baseIndx
+
devices
.
size
());
platformInfo
.
deviceIDs
.
resize
(
devices
.
size
());
platformInfo
.
info
.
devices
.
resize
(
devices
.
size
());
platformInfo
.
devices
.
resize
(
devices
.
size
());
for
(
size_t
j
=
0
;
j
<
devices
.
size
();
++
j
)
{
cl_device_id
device
=
devices
[
j
];
DeviceInfoImpl
&
deviceInfo
=
global_devices
[
baseIndx
+
j
];
deviceInfo
.
info
.
_id
=
baseIndx
+
j
;
deviceInfo
.
platform_id
=
platform
;
deviceInfo
.
device_id
=
device
;
deviceInfo
.
info
.
platform
=
&
platformInfo
.
info
;
platformInfo
.
deviceIDs
[
j
]
=
deviceInfo
.
info
.
_id
;
cl_device_type
type
=
cl_device_type
(
-
1
);
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_TYPE
,
type
));
deviceInfo
.
info
.
deviceType
=
DeviceType
(
type
);
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_PROFILE
,
deviceInfo
.
info
.
deviceProfile
));
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_VERSION
,
deviceInfo
.
info
.
deviceVersion
));
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_NAME
,
deviceInfo
.
info
.
deviceName
));
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_VENDOR
,
deviceInfo
.
info
.
deviceVendor
));
cl_uint
vendorID
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_VENDOR_ID
,
vendorID
));
deviceInfo
.
info
.
deviceVendorId
=
vendorID
;
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DRIVER_VERSION
,
deviceInfo
.
info
.
deviceDriverVersion
));
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_EXTENSIONS
,
deviceInfo
.
info
.
deviceExtensions
));
parseOpenCLVersion
(
deviceInfo
.
info
.
deviceVersion
,
deviceInfo
.
info
.
deviceVersionMajor
,
deviceInfo
.
info
.
deviceVersionMinor
);
size_t
maxWorkGroupSize
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_MAX_WORK_GROUP_SIZE
,
maxWorkGroupSize
));
deviceInfo
.
info
.
maxWorkGroupSize
=
maxWorkGroupSize
;
cl_uint
maxDimensions
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
,
maxDimensions
));
std
::
vector
<
size_t
>
maxWorkItemSizes
(
maxDimensions
);
openCLSafeCall
(
clGetDeviceInfo
(
device
,
CL_DEVICE_MAX_WORK_ITEM_SIZES
,
sizeof
(
size_t
)
*
maxDimensions
,
(
void
*
)
&
maxWorkItemSizes
[
0
],
0
));
deviceInfo
.
info
.
maxWorkItemSizes
=
maxWorkItemSizes
;
cl_uint
maxComputeUnits
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_MAX_COMPUTE_UNITS
,
maxComputeUnits
));
deviceInfo
.
info
.
maxComputeUnits
=
maxComputeUnits
;
cl_ulong
localMemorySize
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_LOCAL_MEM_SIZE
,
localMemorySize
));
deviceInfo
.
info
.
localMemorySize
=
(
size_t
)
localMemorySize
;
cl_ulong
maxMemAllocSize
=
0
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_MAX_MEM_ALLOC_SIZE
,
maxMemAllocSize
));
deviceInfo
.
info
.
maxMemAllocSize
=
(
size_t
)
maxMemAllocSize
;
cl_bool
unifiedMemory
=
false
;
openCLSafeCall
(
getScalarInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_HOST_UNIFIED_MEMORY
,
unifiedMemory
));
deviceInfo
.
info
.
isUnifiedMemory
=
unifiedMemory
!=
0
;
//initialize extra options for compilation. Currently only fp64 is included.
//Assume 4KB is enough to store all possible extensions.
openCLSafeCall
(
getStringInfo
(
clGetDeviceInfo
,
device
,
CL_DEVICE_EXTENSIONS
,
deviceInfo
.
info
.
deviceExtensions
));
size_t
fp64_khr
=
deviceInfo
.
info
.
deviceExtensions
.
find
(
"cl_khr_fp64"
);
if
(
fp64_khr
!=
std
::
string
::
npos
)
{
deviceInfo
.
info
.
compilationExtraOptions
+=
"-D DOUBLE_SUPPORT"
;
deviceInfo
.
info
.
haveDoubleSupport
=
true
;
}
else
{
deviceInfo
.
info
.
haveDoubleSupport
=
false
;
}
size_t
intel_platform
=
platformInfo
.
info
.
platformVendor
.
find
(
"Intel"
);
if
(
intel_platform
!=
std
::
string
::
npos
)
{
deviceInfo
.
info
.
compilationExtraOptions
+=
" -D INTEL_DEVICE"
;
deviceInfo
.
info
.
isIntelDevice
=
true
;
}
else
{
deviceInfo
.
info
.
isIntelDevice
=
false
;
}
platformInfo
.
deviceIDs
[
j
]
=
baseIndx
+
j
;
deviceInfo
.
init
(
baseIndx
+
j
,
platformInfo
,
device
);
}
}
}
...
...
@@ -472,7 +497,7 @@ static int initializeOpenCLDevices()
for
(
size_t
j
=
0
;
j
<
platformInfo
.
deviceIDs
.
size
();
++
j
)
{
DeviceInfoImpl
&
deviceInfo
=
global_devices
[
platformInfo
.
deviceIDs
[
j
]];
platformInfo
.
info
.
devices
[
j
]
=
&
deviceInfo
.
i
nfo
;
platformInfo
.
devices
[
j
]
=
&
deviceI
nfo
;
}
}
...
...
@@ -491,6 +516,8 @@ DeviceInfo::DeviceInfo()
// nothing
}
DeviceInfo
::~
DeviceInfo
()
{
}
PlatformInfo
::
PlatformInfo
()
:
_id
(
-
1
),
platformVersionMajor
(
0
),
platformVersionMinor
(
0
)
...
...
@@ -498,6 +525,8 @@ PlatformInfo::PlatformInfo()
// nothing
}
PlatformInfo
::~
PlatformInfo
()
{
}
class
ContextImpl
;
struct
CommandQueue
...
...
@@ -535,34 +564,96 @@ cv::TLSData<CommandQueue> commandQueueTLSData;
class
ContextImpl
:
public
Context
{
public
:
c
onst
c
l_device_id
clDeviceID
;
cl_device_id
clDeviceID
;
cl_context
clContext
;
const
DeviceInfo
&
deviceInfo
;
const
DeviceInfo
Impl
&
deviceInfoImpl
;
protected
:
ContextImpl
(
const
DeviceInfo
&
deviceInfo
,
cl_device_id
clDeviceID
)
:
clDeviceID
(
clDeviceID
),
clContext
(
NULL
),
deviceInfo
(
deviceInfo
)
ContextImpl
(
const
DeviceInfo
Impl
&
_deviceInfoImpl
,
cl_context
context
)
:
clDeviceID
(
_deviceInfoImpl
.
device_id
),
clContext
(
context
),
deviceInfoImpl
(
_deviceInfoImpl
)
{
// nothing
#ifdef CL_VERSION_1_2
if
(
supportsFeature
(
FEATURE_CL_VER_1_2
))
{
openCLSafeCall
(
clRetainDevice
(
clDeviceID
));
}
#endif
openCLSafeCall
(
clRetainContext
(
clContext
));
ContextImpl
*
old
=
NULL
;
{
cv
::
AutoLock
lock
(
getCurrentContextMutex
());
old
=
currentContext
;
currentContext
=
this
;
}
if
(
old
!=
NULL
)
{
delete
old
;
}
}
~
ContextImpl
()
{
CV_Assert
(
this
!=
currentContext
);
#ifdef CL_VERSION_1_2
if
(
supportsFeature
(
FEATURE_CL_VER_1_2
))
{
openCLSafeCall
(
clReleaseDevice
(
clDeviceID
));
}
#endif
if
(
deviceInfoImpl
.
_id
<
0
)
// not in the global registry, so we should cleanup it
{
#ifdef CL_VERSION_1_2
if
(
supportsFeature
(
FEATURE_CL_VER_1_2
))
{
openCLSafeCall
(
clReleaseDevice
(
deviceInfoImpl
.
device_id
));
}
#endif
PlatformInfoImpl
*
platformImpl
=
(
PlatformInfoImpl
*
)(
deviceInfoImpl
.
platform
);
delete
platformImpl
;
delete
const_cast
<
DeviceInfoImpl
*>
(
&
deviceInfoImpl
);
}
clDeviceID
=
NULL
;
#ifdef WIN32
// if process is on termination stage (ExitProcess was called and other threads were terminated)
// then disable command queue release because it may cause program hang
if
(
!
__termination
)
#endif
{
if
(
clContext
)
{
openCLSafeCall
(
clReleaseContext
(
clContext
));
}
}
clContext
=
NULL
;
}
~
ContextImpl
();
public
:
static
void
setContext
(
const
DeviceInfo
*
deviceInfo
);
static
void
initializeContext
(
void
*
pClPlatform
,
void
*
pClContext
,
void
*
pClDevice
);
bool
supportsFeature
(
FEATURE_TYPE
featureType
)
const
;
static
void
cleanupContext
(
void
);
static
ContextImpl
*
getContext
();
private
:
ContextImpl
(
const
ContextImpl
&
);
// disabled
ContextImpl
&
operator
=
(
const
ContextImpl
&
);
// disabled
static
ContextImpl
*
currentContext
;
};
static
ContextImpl
*
currentContext
=
NULL
;
ContextImpl
*
ContextImpl
::
currentContext
=
NULL
;
static
bool
__deviceSelected
=
false
;
Context
*
Context
::
getContext
()
{
return
ContextImpl
::
getContext
();
}
ContextImpl
*
ContextImpl
::
getContext
()
{
if
(
currentContext
==
NULL
)
{
...
...
@@ -606,7 +697,7 @@ bool Context::supportsFeature(FEATURE_TYPE featureType) const
const
DeviceInfo
&
Context
::
getDeviceInfo
()
const
{
return
((
ContextImpl
*
)
this
)
->
deviceInfo
;
return
((
ContextImpl
*
)
this
)
->
deviceInfo
Impl
;
}
const
void
*
Context
::
getOpenCLContextPtr
()
const
...
...
@@ -636,34 +727,18 @@ bool ContextImpl::supportsFeature(FEATURE_TYPE featureType) const
switch
(
featureType
)
{
case
FEATURE_CL_INTEL_DEVICE
:
return
deviceInfo
.
isIntelDevice
;
return
deviceInfo
Impl
.
isIntelDevice
;
case
FEATURE_CL_DOUBLE
:
return
deviceInfo
.
haveDoubleSupport
;
return
deviceInfo
Impl
.
haveDoubleSupport
;
case
FEATURE_CL_UNIFIED_MEM
:
return
deviceInfo
.
isUnifiedMemory
;
return
deviceInfo
Impl
.
isUnifiedMemory
;
case
FEATURE_CL_VER_1_2
:
return
deviceInfo
.
deviceVersionMajor
>
1
||
(
deviceInfo
.
deviceVersionMajor
==
1
&&
deviceInfo
.
deviceVersionMinor
>=
2
);
return
deviceInfo
Impl
.
deviceVersionMajor
>
1
||
(
deviceInfoImpl
.
deviceVersionMajor
==
1
&&
deviceInfoImpl
.
deviceVersionMinor
>=
2
);
}
CV_Error
(
CV_StsBadArg
,
"Invalid feature type"
);
return
false
;
}
ContextImpl
::~
ContextImpl
()
{
#ifdef WIN32
// if process is on termination stage (ExitProcess was called and other threads were terminated)
// then disable command queue release because it may cause program hang
if
(
!
__termination
)
#endif
{
if
(
clContext
)
{
openCLSafeCall
(
clReleaseContext
(
clContext
));
}
}
clContext
=
NULL
;
}
void
fft_teardown
();
void
clBlasTeardown
();
...
...
@@ -672,46 +747,58 @@ void ContextImpl::cleanupContext(void)
fft_teardown
();
clBlasTeardown
();
cv
::
AutoLock
lock
(
__module
.
currentContextMutex
);
cv
::
AutoLock
lock
(
getCurrentContextMutex
()
);
if
(
currentContext
)
delete
currentContext
;
{
ContextImpl
*
ctx
=
currentContext
;
currentContext
=
NULL
;
delete
ctx
;
}
}
void
ContextImpl
::
setContext
(
const
DeviceInfo
*
deviceInfo
)
{
CV_Assert
(
deviceInfo
->
_id
>=
0
&&
deviceInfo
->
_id
<
(
int
)
global_devices
.
size
());
CV_Assert
(
deviceInfo
->
_id
>=
0
);
// we can't specify custom devices
CV_Assert
(
deviceInfo
->
_id
<
(
int
)
global_devices
.
size
());
{
cv
::
AutoLock
lock
(
__module
.
currentContextMutex
);
cv
::
AutoLock
lock
(
getCurrentContextMutex
()
);
if
(
currentContext
)
{
if
(
currentContext
->
deviceInfo
.
_id
==
deviceInfo
->
_id
)
if
(
currentContext
->
deviceInfo
Impl
.
_id
==
deviceInfo
->
_id
)
return
;
}
}
DeviceInfoImpl
&
infoImpl
=
global_devices
[
deviceInfo
->
_id
];
CV_Assert
(
deviceInfo
==
&
infoImpl
.
info
);
CV_Assert
(
deviceInfo
==
&
infoImpl
);
cl_int
status
=
0
;
cl_context_properties
cps
[
3
]
=
{
CL_CONTEXT_PLATFORM
,
(
cl_context_properties
)(
infoImpl
.
platform_id
),
0
};
cl_context
clContext
=
clCreateContext
(
cps
,
1
,
&
infoImpl
.
device_id
,
NULL
,
NULL
,
&
status
);
openCLVerifyCall
(
status
);
ContextImpl
*
ctx
=
new
ContextImpl
(
infoImpl
.
info
,
infoImpl
.
device_id
);
ctx
->
clContext
=
clContext
;
ContextImpl
*
ctx
=
new
ContextImpl
(
infoImpl
,
clContext
);
clReleaseContext
(
clContext
);
(
void
)
ctx
;
}
ContextImpl
*
old
=
NULL
;
{
cv
::
AutoLock
lock
(
__module
.
currentContextMutex
);
old
=
currentContext
;
currentContext
=
ctx
;
}
if
(
old
!=
NULL
)
{
delete
old
;
}
void
ContextImpl
::
initializeContext
(
void
*
pClPlatform
,
void
*
pClContext
,
void
*
pClDevice
)
{
CV_Assert
(
pClPlatform
!=
NULL
);
CV_Assert
(
pClContext
!=
NULL
);
CV_Assert
(
pClDevice
!=
NULL
);
cl_platform_id
platform
=
*
(
cl_platform_id
*
)
pClPlatform
;
cl_context
context
=
*
(
cl_context
*
)
pClContext
;
cl_device_id
device
=
*
(
cl_device_id
*
)
pClDevice
;
PlatformInfoImpl
*
platformInfoImpl
=
new
PlatformInfoImpl
();
platformInfoImpl
->
init
(
-
1
,
platform
);
DeviceInfoImpl
*
deviceInfoImpl
=
new
DeviceInfoImpl
();
deviceInfoImpl
->
init
(
-
1
,
*
platformInfoImpl
,
device
);
ContextImpl
*
ctx
=
new
ContextImpl
(
*
deviceInfoImpl
,
context
);
(
void
)
ctx
;
}
void
CommandQueue
::
create
(
ContextImpl
*
context
)
...
...
@@ -735,7 +822,7 @@ int getOpenCLPlatforms(PlatformsInfo& platforms)
for
(
size_t
id
=
0
;
id
<
global_platforms
.
size
();
++
id
)
{
PlatformInfoImpl
&
impl
=
global_platforms
[
id
];
platforms
.
push_back
(
&
impl
.
info
);
platforms
.
push_back
(
&
impl
);
}
return
platforms
.
size
();
...
...
@@ -765,9 +852,9 @@ int getOpenCLDevices(std::vector<const DeviceInfo*> &devices, int deviceType, co
for
(
size_t
id
=
0
;
id
<
global_devices
.
size
();
++
id
)
{
DeviceInfoImpl
&
deviceInfo
=
global_devices
[
id
];
if
(((
int
)
deviceInfo
.
info
.
deviceType
&
deviceType
)
!=
0
)
if
(((
int
)
deviceInfo
.
deviceType
&
deviceType
)
!=
0
)
{
devices
.
push_back
(
&
deviceInfo
.
info
);
devices
.
push_back
(
&
deviceInfo
);
}
}
}
...
...
@@ -800,6 +887,20 @@ void setDevice(const DeviceInfo* info)
}
}
void
initializeContext
(
void
*
pClPlatform
,
void
*
pClContext
,
void
*
pClDevice
)
{
try
{
ContextImpl
::
initializeContext
(
pClPlatform
,
pClContext
,
pClDevice
);
__deviceSelected
=
true
;
}
catch
(...)
{
__deviceSelected
=
true
;
throw
;
}
}
bool
supportsFeature
(
FEATURE_TYPE
featureType
)
{
return
Context
::
getContext
()
->
supportsFeature
(
featureType
);
...
...
modules/ocl/test/test_api.cpp
View file @
17ca7f95
...
...
@@ -40,7 +40,7 @@
//M*/
#include "test_precomp.hpp"
#include "opencv2/ocl/cl_runtime/cl_runtime.hpp" // for OpenCL types
: cl_mem
#include "opencv2/ocl/cl_runtime/cl_runtime.hpp" // for OpenCL types
& functions
TEST
(
TestAPI
,
openCLExecuteKernelInterop
)
{
...
...
@@ -78,3 +78,87 @@ TEST(TestAPI, openCLExecuteKernelInterop)
EXPECT_LE
(
checkNorm
(
cpuMat
,
dst
),
1e-3
);
}
// This test must be DISABLED by default!
// (We can't restore original context for other tests)
TEST
(
TestAPI
,
DISABLED_InitializationFromHandles
)
{
#define MAX_PLATFORMS 16
cl_platform_id
platforms
[
MAX_PLATFORMS
]
=
{
NULL
};
cl_uint
numPlatforms
=
0
;
cl_int
status
=
::
clGetPlatformIDs
(
MAX_PLATFORMS
,
&
platforms
[
0
],
&
numPlatforms
);
ASSERT_EQ
(
CL_SUCCESS
,
status
)
<<
"clGetPlatformIDs"
;
ASSERT_NE
(
0
,
(
int
)
numPlatforms
);
int
selectedPlatform
=
0
;
cl_platform_id
platform
=
platforms
[
selectedPlatform
];
ASSERT_NE
((
void
*
)
NULL
,
platform
);
cl_device_id
device
=
NULL
;
status
=
::
clGetDeviceIDs
(
platform
,
CL_DEVICE_TYPE_ALL
,
1
,
&
device
,
NULL
);
ASSERT_EQ
(
CL_SUCCESS
,
status
)
<<
"clGetDeviceIDs"
;
ASSERT_NE
((
void
*
)
NULL
,
device
);
cl_context_properties
cps
[
3
]
=
{
CL_CONTEXT_PLATFORM
,
(
cl_context_properties
)(
platform
),
0
};
cl_context
context
=
::
clCreateContext
(
cps
,
1
,
&
device
,
NULL
,
NULL
,
&
status
);
ASSERT_EQ
(
CL_SUCCESS
,
status
)
<<
"clCreateContext"
;
ASSERT_NE
((
void
*
)
NULL
,
context
);
ASSERT_NO_THROW
(
cv
::
ocl
::
initializeContext
(
&
platform
,
&
context
,
&
device
));
status
=
::
clReleaseContext
(
context
);
ASSERT_EQ
(
CL_SUCCESS
,
status
)
<<
"clReleaseContext"
;
#ifdef CL_VERSION_1_2
#if 1
{
cv
::
ocl
::
Context
*
ctx
=
cv
::
ocl
::
Context
::
getContext
();
ASSERT_NE
((
void
*
)
NULL
,
ctx
);
if
(
ctx
->
supportsFeature
(
cv
::
ocl
::
FEATURE_CL_VER_1_2
))
// device supports OpenCL 1.2+
{
status
=
::
clReleaseDevice
(
device
);
ASSERT_EQ
(
CL_SUCCESS
,
status
)
<<
"clReleaseDevice"
;
}
}
#else // code below doesn't work on Linux (SEGFAULTs on 1.1- devices are not handled via exceptions)
try
{
status
=
::
clReleaseDevice
(
device
);
// NOTE This works only with !DEVICES! that supports OpenCL 1.2
(
void
)
status
;
// no check
}
catch
(...)
{
// nothing, there is no problem
}
#endif
#endif
// print the name of current device
cv
::
ocl
::
Context
*
ctx
=
cv
::
ocl
::
Context
::
getContext
();
ASSERT_NE
((
void
*
)
NULL
,
ctx
);
const
cv
::
ocl
::
DeviceInfo
&
deviceInfo
=
ctx
->
getDeviceInfo
();
std
::
cout
<<
"Device name: "
<<
deviceInfo
.
deviceName
<<
std
::
endl
;
std
::
cout
<<
"Platform name: "
<<
deviceInfo
.
platform
->
platformName
<<
std
::
endl
;
ASSERT_EQ
(
context
,
*
(
cl_context
*
)
ctx
->
getOpenCLContextPtr
());
ASSERT_EQ
(
device
,
*
(
cl_device_id
*
)
ctx
->
getOpenCLDeviceIDPtr
());
// do some calculations and check results
cv
::
RNG
rng
;
Size
sz
(
100
,
100
);
cv
::
Mat
srcMat
=
cvtest
::
randomMat
(
rng
,
sz
,
CV_32FC4
,
-
10
,
10
,
false
);
cv
::
Mat
dstMat
;
cv
::
ocl
::
oclMat
srcGpuMat
(
srcMat
);
cv
::
ocl
::
oclMat
dstGpuMat
;
cv
::
Scalar
v
=
cv
::
Scalar
::
all
(
1
);
cv
::
add
(
srcMat
,
v
,
dstMat
);
cv
::
ocl
::
add
(
srcGpuMat
,
v
,
dstGpuMat
);
cv
::
Mat
dstGpuMatMap
;
dstGpuMat
.
download
(
dstGpuMatMap
);
EXPECT_LE
(
checkNorm
(
dstMat
,
dstGpuMatMap
),
1e-3
);
}
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