Skip to content

Commit

Permalink
Added context
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Aug 8, 2018
1 parent 08fc641 commit ebad360
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 39 deletions.
4 changes: 4 additions & 0 deletions src/analysis/raster/qgsninecellfilter.cpp
Expand Up @@ -220,6 +220,10 @@ int QgsNineCellFilter::processRasterGPU( const QString &source, QgsFeedback *fee
return 6;
}

// Prepare context
cl::Context ctx = QgsOpenClUtils::context();
cl::Context::setDefault( ctx );

//keep only three scanlines in memory at a time, make room for initial and final nodata
QgsOpenClUtils::CPLAllocator<float> scanLine1( xSize + 2 );
QgsOpenClUtils::CPLAllocator<float> scanLine2( xSize + 2 );
Expand Down
98 changes: 67 additions & 31 deletions src/core/qgsopenclutils.cpp
Expand Up @@ -26,55 +26,79 @@
QLatin1String QgsOpenClUtils::SETTINGS_KEY = QLatin1Literal( "OpenClEnabled" );
QLatin1String QgsOpenClUtils::LOGMESSAGE_TAG = QLatin1Literal( "OpenCL" );
bool QgsOpenClUtils::sAvailable = false;

cl::Platform QgsOpenClUtils::sPlatform = cl::Platform();
cl::Device QgsOpenClUtils::sDevice = cl::Device();

void QgsOpenClUtils::init()
{
static bool initialized = false;
if ( ! initialized )
{
std::vector<cl::Platform> platforms;
cl::Platform::get( &platforms );
cl::Platform plat;
cl::Device dev;
for ( auto &p : platforms )
try
{
std::string platver = p.getInfo<CL_PLATFORM_VERSION>();
QgsDebugMsg( QStringLiteral( "Found OpenCL platform %1: %2" ).arg( QString::fromStdString( platver ), QString::fromStdString( p.getInfo<CL_PLATFORM_NAME>() ) ) );
if ( platver.find( "OpenCL 1." ) != std::string::npos )
std::vector<cl::Platform> platforms;
cl::Platform::get( &platforms );
cl::Platform plat;
cl::Device dev;
for ( auto &p : platforms )
{
std::vector<cl::Device> devices;
// Check for a GPU device
p.getDevices( CL_DEVICE_TYPE_GPU, &devices );
if ( devices.size() > 0 )
std::string platver = p.getInfo<CL_PLATFORM_VERSION>();
QgsDebugMsg( QStringLiteral( "Found OpenCL platform %1: %2" ).arg( QString::fromStdString( platver ), QString::fromStdString( p.getInfo<CL_PLATFORM_NAME>() ) ) );
if ( platver.find( "OpenCL 1." ) != std::string::npos )
{
// Got one!
plat = p;
dev = devices[0];
break;
std::vector<cl::Device> devices;
// Check for a GPU device
try
{
p.getDevices( CL_DEVICE_TYPE_GPU, &devices );
}
catch ( cl::Error &e )
{
QgsDebugMsgLevel( 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>() ) ), 2 );
}
if ( devices.size() > 0 )
{
// Got one!
plat = p;
dev = devices[0];
break;
}
}
}
}
if ( plat() == 0 )
{
QgsMessageLog::logMessage( QObject::tr( "No OpenCL 1.x platform with GPU found." ), LOGMESSAGE_TAG, Qgis::Warning );
sAvailable = false;
}
else
{
cl::Platform newP = cl::Platform::setDefault( plat );
if ( newP != plat )
if ( plat() == 0 )
{
QgsMessageLog::logMessage( QObject::tr( "Error setting default platform." ), LOGMESSAGE_TAG, Qgis::Warning );
QgsMessageLog::logMessage( QObject::tr( "No OpenCL 1.x platform with GPU found." ), LOGMESSAGE_TAG, Qgis::Warning );
sAvailable = false;
}
else
{
cl::Device::setDefault( dev );
QgsDebugMsg( QStringLiteral( "Found OpenCL device %1" ).arg( QString::fromStdString( dev.getInfo<CL_DEVICE_NAME>() ) ) );
sAvailable = true;
cl::Platform newP = cl::Platform::setDefault( plat );
if ( newP != plat )
{
QgsMessageLog::logMessage( QObject::tr( "Error setting default platform." ), LOGMESSAGE_TAG, Qgis::Warning );
sAvailable = false;
}
else
{
cl::Device::setDefault( dev );
QgsDebugMsgLevel( QStringLiteral( "Found OpenCL device %1" )
.arg( QString::fromStdString( dev.getInfo<CL_DEVICE_NAME>() ) ), 2 );
sAvailable = true;
sDevice = dev;
sPlatform = plat;
}
}
}
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::Critical );
sAvailable = false;
}
initialized = true;
}
}
Expand Down Expand Up @@ -220,3 +244,15 @@ QString QgsOpenClUtils::errorText( const int errorCode )
default: return QStringLiteral( "CL_UNKNOWN_ERROR" );
}
}

cl::Context QgsOpenClUtils::context()
{
if ( available() && sPlatform() && sDevice() )
{
return cl::Context( sDevice );
}
else
{
return cl::Context();
}
}
5 changes: 4 additions & 1 deletion src/core/qgsopenclutils.h
Expand Up @@ -47,6 +47,8 @@ class CORE_EXPORT QgsOpenClUtils
static QLatin1String LOGMESSAGE_TAG;
static QString errorText( const int errorCode );

static cl::Context context();

/**
* Tiny smart-pointer wrapper around CPLMalloc and CPLFree: this is needed because
* OpenCL C++ API may throw exceptions
Expand Down Expand Up @@ -107,8 +109,9 @@ class CORE_EXPORT QgsOpenClUtils
QgsOpenClUtils();
static void init();
static bool sAvailable;
static cl::Device sDevice;
static cl::Platform sPlatform;
static QLatin1String SETTINGS_KEY;

};


Expand Down
20 changes: 13 additions & 7 deletions tests/src/core/testqgsopenclutils.cpp
Expand Up @@ -34,6 +34,7 @@ class TestQgsOpenClUtils: public QObject
void TestDisable();
void TestAvailable();
void testRunProgram();
void testContext();

private:

Expand Down Expand Up @@ -76,6 +77,9 @@ void TestQgsOpenClUtils::testRunProgram()

QVERIFY( err == 0 );

cl::Context ctx = QgsOpenClUtils::context();
cl::Context::setDefault( ctx );

std::vector<float> a_vec = {1, 10, 100};
std::vector<float> b_vec = {1, 10, 100};
std::vector<float> c_vec = {-1, -1, -1};
Expand All @@ -85,11 +89,9 @@ void TestQgsOpenClUtils::testRunProgram()

try
{
cl::Program program( source( ), true );

// This also works:
//cl::Program program( source( ) );
//program.build("-cl-std=CL1.1");
cl::Program program( source( ) );
program.build( "-cl-std=CL1.1" );

auto kernel =
cl::KernelFunctor <
Expand All @@ -108,7 +110,7 @@ void TestQgsOpenClUtils::testRunProgram()
}
catch ( cl::BuildError e )
{
qDebug() << "OPENCL Error: " << e.err() << e.what();
qDebug() << "OPENCL Build Error: " << QgsOpenClUtils::errorText( e.err() ) << e.what();
cl::BuildLogType build_logs = e.getBuildLog();
QString build_log;
if ( build_logs.size() > 0 )
Expand All @@ -125,11 +127,15 @@ void TestQgsOpenClUtils::testRunProgram()
cl::copy( c_buf, c_vec.begin(), c_vec.end() );
for ( size_t i = 0; i < c_vec.size(); ++i )
{
QCOMPARE( a_vec[i] + b_vec[i], c_vec[i] );
qDebug() << c_vec[i];
QCOMPARE( c_vec[i], a_vec[i] + b_vec[i] );
}
}

void TestQgsOpenClUtils::testContext()
{
QVERIFY( QgsOpenClUtils::context()() != nullptr );
}


QGSTEST_MAIN( TestQgsOpenClUtils )
#include "testqgsopenclutils.moc"

0 comments on commit ebad360

Please sign in to comment.