Skip to content

Commit

Permalink
Fix build error with MSVC on qgsopenclutils.cpp (master only)
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault authored and nyalldawson committed Dec 9, 2024
1 parent ece4058 commit e75dfca
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 92 deletions.
198 changes: 106 additions & 92 deletions src/core/qgsopenclutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,139 +341,153 @@ QString QgsOpenClUtils::deviceId( const cl::Device device )
.arg( deviceInfo( QgsOpenClUtils::Info::Type, device ) );
}

#if defined(_MSC_VER)
static void emitLogMessageForSEHException( int exceptionCode )
{
QgsMessageLog::logMessage( QObject::tr( "Unexpected exception of code %1 occurred while searching for OpenCL device. Note that the application may become unreliable and may need to be restarted." ).arg( exceptionCode ),
LOGMESSAGE_TAG, Qgis::MessageLevel::Warning );
}
#endif

bool QgsOpenClUtils::activate( const QString &preferredDeviceId )
{
#if defined(_MSC_VER)
// Try to capture hard crashes such as https://github.com/qgis/QGIS/issues/59617
__try
{
// We cannot combine together __try and try in the same function.
return activateInternal( preferredDeviceId );
}
__except ( EXCEPTION_EXECUTE_HANDLER )
{
emitLogMessageForSEHException( GetExceptionCode() );
return false;
}
#else
return activateInternal( preferredDeviceId );
#endif
}

bool QgsOpenClUtils::activateInternal( const QString &preferredDeviceId )
{
if ( deviceId( activeDevice() ) == preferredDeviceId )
{
sAvailable = true;
return false;
}
#if defined(_MSC_VER)
// Try to capture hard crashes such as https://github.com/qgis/QGIS/issues/59617
__try

try
{
#endif
try
std::vector<cl::Platform> platforms;
cl::Platform::get( &platforms );
cl::Platform plat;
cl::Device dev;
bool deviceFound = false;
for ( const auto &p : platforms )
{
std::vector<cl::Platform> platforms;
cl::Platform::get( &platforms );
cl::Platform plat;
cl::Device dev;
bool deviceFound = false;
for ( const auto &p : platforms )
if ( deviceFound )
break;
const std::string platver = p.getInfo<CL_PLATFORM_VERSION>();
QgsDebugMsgLevel( QStringLiteral( "Found OpenCL platform %1: %2" ).arg( QString::fromStdString( platver ), QString::fromStdString( p.getInfo<CL_PLATFORM_NAME>() ) ), 2 );
if ( platver.find( "OpenCL " ) != std::string::npos )
{
if ( deviceFound )
break;
const std::string platver = p.getInfo<CL_PLATFORM_VERSION>();
QgsDebugMsgLevel( QStringLiteral( "Found OpenCL platform %1: %2" ).arg( QString::fromStdString( platver ), QString::fromStdString( p.getInfo<CL_PLATFORM_NAME>() ) ), 2 );
if ( platver.find( "OpenCL " ) != std::string::npos )
std::vector<cl::Device> devices;
// Search for a device
try
{
std::vector<cl::Device> devices;
// Search for a device
try
p.getDevices( CL_DEVICE_TYPE_ALL, &devices );
// First search for the preferred device
if ( ! preferredDeviceId.isEmpty() )
{
p.getDevices( CL_DEVICE_TYPE_ALL, &devices );
// First search for the preferred device
if ( ! preferredDeviceId.isEmpty() )
for ( const auto &_dev : devices )
{
for ( const auto &_dev : devices )
if ( preferredDeviceId == deviceId( _dev ) )
{
if ( preferredDeviceId == deviceId( _dev ) )
{
// Got one!
plat = p;
dev = _dev;
deviceFound = true;
break;
}
// Got one!
plat = p;
dev = _dev;
deviceFound = true;
break;
}
}
// Not found or preferred device id not set: get the first GPU
if ( ! deviceFound )
}
// Not found or preferred device id not set: get the first GPU
if ( ! deviceFound )
{
for ( const auto &_dev : devices )
{
for ( const auto &_dev : devices )
if ( _dev.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_GPU )
{
if ( _dev.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_GPU )
{
// Got one!
plat = p;
dev = _dev;
deviceFound = true;
break;
}
// Got one!
plat = p;
dev = _dev;
deviceFound = true;
break;
}
}
// Still nothing? Get the first device
if ( ! deviceFound )
}
// Still nothing? Get the first device
if ( ! deviceFound )
{
for ( const auto &_dev : devices )
{
for ( const auto &_dev : devices )
if ( _dev.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_CPU )
{
if ( _dev.getInfo<CL_DEVICE_TYPE>() == CL_DEVICE_TYPE_CPU )
{
// Got one!
plat = p;
dev = _dev;
deviceFound = true;
break;
}
// Got one!
plat = p;
dev = _dev;
deviceFound = true;
break;
}
}
if ( ! deviceFound )
{
QgsMessageLog::logMessage( QObject::tr( "No OpenCL device could be found." ), LOGMESSAGE_TAG, Qgis::MessageLevel::Warning );
}
}
catch ( cl::Error &e )
if ( ! deviceFound )
{
QgsDebugError( QStringLiteral( "Error %1 on platform %3 searching for OpenCL device: %2" )
.arg( errorText( e.err() ),
QString::fromStdString( e.what() ),
QString::fromStdString( p.getInfo<CL_PLATFORM_NAME>() ) ) );
QgsMessageLog::logMessage( QObject::tr( "No OpenCL device could be found." ), LOGMESSAGE_TAG, Qgis::MessageLevel::Warning );
}

}
catch ( cl::Error &e )
{
QgsDebugError( QStringLiteral( "Error %1 on platform %3 searching for OpenCL device: %2" )
.arg( errorText( e.err() ),
QString::fromStdString( e.what() ),
QString::fromStdString( p.getInfo<CL_PLATFORM_NAME>() ) ) );
}

}
if ( ! plat() )
}
if ( ! plat() )
{
QgsMessageLog::logMessage( QObject::tr( "No OpenCL platform found." ), LOGMESSAGE_TAG, Qgis::MessageLevel::Warning );
sAvailable = false;
}
else
{
const cl::Platform newP = cl::Platform::setDefault( plat );
if ( newP != plat )
{
QgsMessageLog::logMessage( QObject::tr( "No OpenCL platform found." ), LOGMESSAGE_TAG, Qgis::MessageLevel::Warning );
QgsMessageLog::logMessage( QObject::tr( "Error setting default platform." ),
LOGMESSAGE_TAG, Qgis::MessageLevel::Warning );
sAvailable = false;
}
else
{
const cl::Platform newP = cl::Platform::setDefault( plat );
if ( newP != plat )
{
QgsMessageLog::logMessage( QObject::tr( "Error setting default platform." ),
LOGMESSAGE_TAG, Qgis::MessageLevel::Warning );
sAvailable = false;
}
else
{
cl::Device::setDefault( dev );
QgsMessageLog::logMessage( QObject::tr( "Active OpenCL device: %1" )
.arg( QString::fromStdString( dev.getInfo<CL_DEVICE_NAME>() ) ),
LOGMESSAGE_TAG, Qgis::MessageLevel::Success );
sAvailable = true;
}
cl::Device::setDefault( dev );
QgsMessageLog::logMessage( QObject::tr( "Active OpenCL device: %1" )
.arg( QString::fromStdString( dev.getInfo<CL_DEVICE_NAME>() ) ),
LOGMESSAGE_TAG, Qgis::MessageLevel::Success );
sAvailable = true;
}
}

catch ( cl::Error &e )
{
QgsMessageLog::logMessage( QObject::tr( "Error %1 searching for OpenCL device: %2" )
.arg( errorText( e.err() ), QString::fromStdString( e.what() ) ),
LOGMESSAGE_TAG, Qgis::MessageLevel::Warning );
sAvailable = false;
}
#if defined(_MSC_VER)
}
__except ( EXCEPTION_EXECUTE_HANDLER )

catch ( cl::Error &e )
{
QgsMessageLog::logMessage( QObject::tr( "Unexpected exception of code %1 occurred while searching for OpenCL device. Note that the application may become unreliable and may need to be restarted." ).arg( GetExceptionCode() ),
QgsMessageLog::logMessage( QObject::tr( "Error %1 searching for OpenCL device: %2" )
.arg( errorText( e.err() ), QString::fromStdString( e.what() ) ),
LOGMESSAGE_TAG, Qgis::MessageLevel::Warning );
sAvailable = false;
}
#endif

return sAvailable;
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsopenclutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ class CORE_EXPORT QgsOpenClUtils
*/
static bool activate( const QString &preferredDeviceId = QString() );

static bool activateInternal( const QString &preferredDeviceId );

/**
* Initialize the OpenCL system by setting and activating the default device.
*/
Expand Down

0 comments on commit e75dfca

Please sign in to comment.