Skip to content

Commit

Permalink
[opencl] Increase test coverage with no-opencl image comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Aug 8, 2018
1 parent 86b60c6 commit 9ff8779
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 37 deletions.
105 changes: 83 additions & 22 deletions tests/src/analysis/testqgsninecellfilters.cpp
Expand Up @@ -29,6 +29,8 @@

#include <QDir>

// If true regenerate raster reference images
const bool REGENERATE_REFERENCES = false;

class TestNineCellFilters : public QObject
{
Expand All @@ -38,18 +40,24 @@ class TestNineCellFilters : public QObject
private slots:

void initTestCase();
void init();

void testHillshade();
void testSlope();
void testAspect();
void testHillshade();
void testRuggedness();
void testTotalCurvature();
#ifdef HAVE_OPENCL
void testHillshadeCl();
void testSlopeCl();
void testAspectCl();
void testRuggednessCl();
#endif

private:

void _rasterCompare( QgsAlignRaster::RasterInfo &out, QgsAlignRaster::RasterInfo &ref );

template <class T> void _testAlg( const QString &name, bool useOpenCl = false );

static QString referenceFile( const QString &name )
Expand All @@ -64,6 +72,13 @@ class TestNineCellFilters : public QObject
};


void TestNineCellFilters::init()
{
#ifdef HAVE_OPENCL
// Reset to default in case some tests mess it up
QgsOpenClUtils::setSourcePath( QDir( QgsApplication::pkgDataPath() ).absoluteFilePath( QStringLiteral( "resources/opencl_programs" ) ) );
#endif
}

void TestNineCellFilters::initTestCase()
{
Expand All @@ -77,16 +92,12 @@ template <class T>
void TestNineCellFilters::_testAlg( const QString &name, bool useOpenCl )
{
#ifdef HAVE_OPENCL
QgsSettings().setValue( QStringLiteral( "useOpenCl" ), true, QgsSettings::Section::Core );
QgsOpenClUtils::setEnabled( useOpenCl );
QString tmpFile( tempFile( name + ( useOpenCl ? "_opencl" : "" ) ) );
#else
Q_UNUSED( useOpenCl );
QString tmpFile( tempFile( name ) );
#endif
QString refFile( referenceFile( name ) );
QgsAlignRaster::RasterInfo in( SRC_FILE );
QSize inSize( in.rasterSize() );
QSizeF inCellSize( in.cellSize( ) );
T ninecellsfilter( SRC_FILE, tmpFile, "GTiff" );
int res = ninecellsfilter.processRaster();
QVERIFY( res == 0 );
Expand All @@ -95,20 +106,20 @@ void TestNineCellFilters::_testAlg( const QString &name, bool useOpenCl )
QgsAlignRaster::RasterInfo out( tmpFile );
QVERIFY( out.isValid() );

// Reference file
QgsAlignRaster::RasterInfo ref( refFile );
QSize refSize( ref.rasterSize() );
QSizeF refCellSize( ref.cellSize( ) );

QCOMPARE( out.rasterSize(), inSize );
QCOMPARE( out.cellSize(), inCellSize );
QCOMPARE( out.rasterSize(), refSize );
QCOMPARE( out.cellSize(), refCellSize );
// Regenerate reference rasters
if ( ! useOpenCl && REGENERATE_REFERENCES )
{
if ( QFile::exists( refFile ) )
{
QFile::remove( refFile );
}
QVERIFY( QFile::copy( tmpFile, refFile ) );
}

double refId1( ref.identify( 4081812, 2431750 ) );
double refId2( ref.identify( 4081312, 2431350 ) );
QVERIFY( qAbs( out.identify( 4081812, 2431750 ) - refId1 ) < 0.0001f );
QVERIFY( qAbs( out.identify( 4081312, 2431350 ) - refId2 ) < 0.0001f );
// Reference
QgsAlignRaster::RasterInfo ref( refFile );
//qDebug() << "Comparing " << tmpFile << refFile;
_rasterCompare( out, ref );

}

Expand All @@ -118,7 +129,6 @@ void TestNineCellFilters::testSlope()
_testAlg<QgsSlopeFilter>( QStringLiteral( "slope" ) );
}


void TestNineCellFilters::testAspect()
{
_testAlg<QgsAspectFilter>( QStringLiteral( "aspect" ) );
Expand All @@ -130,24 +140,75 @@ void TestNineCellFilters::testSlopeCl()
_testAlg<QgsSlopeFilter>( QStringLiteral( "slope" ), true );
}


void TestNineCellFilters::testAspectCl()
{
_testAlg<QgsAspectFilter>( QStringLiteral( "aspect" ), true );
}

void TestNineCellFilters::testHillshadeCl()
{
_testAlg<QgsHillshadeFilter>( QStringLiteral( "hillshade" ), true );
}

void TestNineCellFilters::testRuggednessCl()
{
_testAlg<QgsRuggednessFilter>( QStringLiteral( "ruggedness" ), true );
}

#endif

void TestNineCellFilters::testHillshade()
{
_testAlg<QgsHillshadeFilter>( QStringLiteral( "hillshade" ) );
}


void TestNineCellFilters::testRuggedness()
{
_testAlg<QgsRuggednessFilter>( QStringLiteral( "ruggedness" ) );
}

void TestNineCellFilters::_rasterCompare( QgsAlignRaster::RasterInfo &out, QgsAlignRaster::RasterInfo &ref )
{
QSize refSize( ref.rasterSize() );
QSizeF refCellSize( ref.cellSize( ) );
QgsAlignRaster::RasterInfo in( SRC_FILE );
QSize inSize( in.rasterSize() );
QSizeF inCellSize( in.cellSize( ) );
QCOMPARE( out.rasterSize(), inSize );
QCOMPARE( out.cellSize(), inCellSize );
QCOMPARE( out.rasterSize(), refSize );
QCOMPARE( out.cellSize(), refCellSize );

// If the values differ less than tolerance they are considered equal
double tolerance = 0.0000001;

// Check three points
std::map<int, int> controlPoints;
controlPoints[4081812] = 2431750;
controlPoints[4081312] = 2431350;
controlPoints[4080263] = 2429558;
// South West corner
controlPoints[4081512] = 2431550;
// North east corner
controlPoints[4085367] = 2434940;
// North west corner
controlPoints[4078263] = 2434936;
// South east corner
controlPoints[4085374] = 2428551;

for ( const auto &cp : controlPoints )
{
int x = cp.first;
int y = cp.second;
double outVal = out.identify( x, y );
double refVal = ref.identify( x, y );
double diff( qAbs( outVal - refVal ) );
//qDebug() << outVal << refVal;
//qDebug() << "Identify " << x << "," << y << " diff " << diff << " check: < " << tolerance;
QVERIFY( diff <= tolerance );
}

}

void TestNineCellFilters::testTotalCurvature()
{
Expand Down
38 changes: 23 additions & 15 deletions tests/src/core/testqgsopenclutils.cpp
Expand Up @@ -46,13 +46,15 @@ class TestQgsOpenClUtils: public QObject
void testProgramSource();
void testContext();
void testDevices();
// For performance testing
void testHillshade();

// For benchmarking performance testing
void testHillshadeCPU();
void testHillshadeGPU();

private:

void _testMakeRunProgram();
void _testMakeHillshade( const QString title, const int loops );
void _testMakeHillshade( const int loops );

cl::Program buildProgram( const cl::Context &context, const QString &source )
{
Expand Down Expand Up @@ -205,30 +207,36 @@ void TestQgsOpenClUtils::testDevices()
qDebug() << QgsOpenClUtils::deviceInfo( QgsOpenClUtils::Info::Type, _devices.at( 0 ) );
}

void TestQgsOpenClUtils::_testMakeHillshade( const QString title, const int loops )
void TestQgsOpenClUtils::_testMakeHillshade( const int loops )
{
std::chrono::time_point<std::chrono::system_clock> startTime( std::chrono::system_clock::now() );
for ( int i = 0 ; i < loops; i++ )
{
QgsHillshadeRenderer renderer( mFloat32RasterLayer->dataProvider(), 1, 35.0, 5000.0 );
// Note: CPU time grows linearly with raster dimensions while GPU time is roughly constant
// 900x900 px gives even times on my testing machine
renderer.block( 0, mFloat32RasterLayer->extent(), 900, 900 );
// 200x200 px gives even times on my testing machine
renderer.block( 0, mFloat32RasterLayer->extent(), 200, 200 );
}
qDebug() << QStringLiteral( "%1 average for %2 loops: %3 ms" )
.arg( title )
.arg( loops )
.arg( std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now() - startTime ).count() / loops ) ;
}

void TestQgsOpenClUtils::testHillshade()
void TestQgsOpenClUtils::testHillshadeGPU()
{
QgsOpenClUtils::setEnabled( true );
_testMakeHillshade( QStringLiteral( "OpenCL" ), 5 );
QVERIFY( QgsOpenClUtils::enabled() );
QBENCHMARK
{
_testMakeHillshade( 1 );
}
}

void TestQgsOpenClUtils::testHillshadeCPU()
{
QgsOpenClUtils::setEnabled( false );
_testMakeHillshade( QStringLiteral( "CPU" ), 5 );
QBENCHMARK
{
_testMakeHillshade( 1 );
}
}



QGSTEST_MAIN( TestQgsOpenClUtils )
#include "testqgsopenclutils.moc"

0 comments on commit 9ff8779

Please sign in to comment.