Skip to content

Commit b71a668

Browse files
committedDec 13, 2018
opencl rastercalc fix int input rasters and cast to float
Cast to float all math operations because when the input is not a float or a double opencl raises an error regarding which override should pick. By casting to float we are sure that the right function will be called. This patch also fixes the buffer sizes for short (16bit) and int (32bit) and asserts that siexe of float is 32bit.
1 parent 8c07c99 commit b71a668

File tree

3 files changed

+55
-19
lines changed

3 files changed

+55
-19
lines changed
 

‎src/analysis/raster/qgsrastercalcnode.cpp

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,12 @@ QString QgsRasterCalcNode::toString( bool cStyle ) const
207207
left = mLeft->toString( cStyle );
208208
if ( mRight )
209209
right = mRight->toString( cStyle );
210+
211+
auto floatCast = [ ]( const QString s ) -> QString
212+
{
213+
return QStringLiteral( "(float) ( %1 )" ).arg( s );
214+
};
215+
210216
switch ( mType )
211217
{
212218
case tOperator:
@@ -227,7 +233,7 @@ QString QgsRasterCalcNode::toString( bool cStyle ) const
227233
break;
228234
case opPOW:
229235
if ( cStyle )
230-
result = QStringLiteral( "pow( %1, %2 )" ).arg( left ).arg( right );
236+
result = QStringLiteral( "pow( %1, %2 )" ).arg( floatCast( left ) ).arg( floatCast( right ) );
231237
else
232238
result = QStringLiteral( "%1^%2" ).arg( left ).arg( right );
233239
break;
@@ -265,31 +271,58 @@ QString QgsRasterCalcNode::toString( bool cStyle ) const
265271
result = QStringLiteral( "%1 OR %2" ).arg( left ).arg( right );
266272
break;
267273
case opSQRT:
268-
result = QStringLiteral( "sqrt( %1 )" ).arg( left );
274+
if ( cStyle )
275+
result = QStringLiteral( "sqrt( %1 )" ).arg( floatCast( left ) );
276+
else
277+
result = QStringLiteral( "sqrt( %1 )" ).arg( left );
269278
break;
270279
case opSIN:
271-
result = QStringLiteral( "sin( %1 )" ).arg( left );
280+
if ( cStyle )
281+
result = QStringLiteral( "sin( %1 )" ).arg( floatCast( left ) );
282+
else
283+
result = QStringLiteral( "sin( %1 )" ).arg( left );
272284
break;
273285
case opCOS:
274-
result = QStringLiteral( "cos( %1 )" ).arg( left );
286+
if ( cStyle )
287+
result = QStringLiteral( "cos( %1 )" ).arg( floatCast( left ) );
288+
else
289+
result = QStringLiteral( "cos( %1 )" ).arg( left );
275290
break;
276291
case opTAN:
277-
result = QStringLiteral( "tan( %1 )" ).arg( left );
292+
if ( cStyle )
293+
result = QStringLiteral( "tan( %1 )" ).arg( floatCast( left ) );
294+
else
295+
result = QStringLiteral( "tan( %1 )" ).arg( left );
278296
break;
279297
case opASIN:
280-
result = QStringLiteral( "asin( %1 )" ).arg( left );
298+
if ( cStyle )
299+
result = QStringLiteral( "asin( %1 )" ).arg( floatCast( left ) );
300+
else
301+
result = QStringLiteral( "asin( %1 )" ).arg( left );
281302
break;
282303
case opACOS:
283-
result = QStringLiteral( "acos( %1 )" ).arg( left );
304+
if ( cStyle )
305+
result = QStringLiteral( "acos( %1 )" ).arg( floatCast( left ) );
306+
else
307+
result = QStringLiteral( "acos( %1 )" ).arg( left );
284308
break;
285309
case opATAN:
286-
result = QStringLiteral( "atan( %1 )" ).arg( left );
310+
if ( cStyle )
311+
result = QStringLiteral( "atan( %1 )" ).arg( floatCast( left ) );
312+
else
313+
result = QStringLiteral( "atan( %1 )" ).arg( left );
287314
break;
288315
case opLOG:
289-
result = QStringLiteral( "log( %1 )" ).arg( left );
316+
if ( cStyle )
317+
result = QStringLiteral( "log( %1 )" ).arg( floatCast( left ) );
318+
else
319+
result = QStringLiteral( "log( %1 )" ).arg( left );
290320
break;
291321
case opLOG10:
292-
result = QStringLiteral( "log10( %1 )" ).arg( left );
322+
if ( cStyle )
323+
result = QStringLiteral( "log10( %1 )" ).arg( floatCast( left ) );
324+
else
325+
result = QStringLiteral( "log10( %1 )" ).arg( left );
293326
break;
294327
case opNONE:
295328
break;

‎src/analysis/raster/qgsrastercalculator.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -370,13 +370,13 @@ QgsRasterCalculator::Result QgsRasterCalculator::processCalculationGPU( std::uni
370370
entry.typeName = QStringLiteral( "unsigned int" );
371371
break;
372372
case Qgis::DataType::Int16:
373-
entry.typeName = QStringLiteral( "int" );
373+
entry.typeName = QStringLiteral( "short" );
374374
break;
375375
case Qgis::DataType::UInt32:
376-
entry.typeName = QStringLiteral( "unsigned long" );
376+
entry.typeName = QStringLiteral( "unsigned int" );
377377
break;
378378
case Qgis::DataType::Int32:
379-
entry.typeName = QStringLiteral( "long" );
379+
entry.typeName = QStringLiteral( "int" );
380380
break;
381381
case Qgis::DataType::Float32:
382382
entry.typeName = QStringLiteral( "float" );
@@ -422,7 +422,7 @@ QgsRasterCalculator::Result QgsRasterCalculator::processCalculationGPU( std::uni
422422
// Inputs:
423423
##INPUT_DESC##
424424
// Expression: ##EXPRESSION_ORIGINAL##
425-
__kernel void rasterCalculator( ##INPUT##,
425+
__kernel void rasterCalculator( ##INPUT##
426426
__global float *resultLine
427427
)
428428
{
@@ -439,16 +439,18 @@ QgsRasterCalculator::Result QgsRasterCalculator::processCalculationGPU( std::uni
439439
inputDesc.append( QStringLiteral( " // %1 = %2" ).arg( ref.varName ).arg( ref.name ) );
440440
}
441441
programTemplate = programTemplate.replace( QStringLiteral( "##INPUT_DESC##" ), inputDesc.join( '\n' ) );
442-
programTemplate = programTemplate.replace( QStringLiteral( "##INPUT##" ), inputArgs.join( ',' ) );
442+
programTemplate = programTemplate.replace( QStringLiteral( "##INPUT##" ), inputArgs.length() ? ( inputArgs.join( ',' ).append( ',' ) ) : QChar( ' ' ) );
443443
programTemplate = programTemplate.replace( QStringLiteral( "##EXPRESSION##" ), cExpression );
444444
programTemplate = programTemplate.replace( QStringLiteral( "##EXPRESSION_ORIGINAL##" ), calcNode->toString( ) );
445445

446-
//qDebug() << programTemplate;
446+
qDebug() << programTemplate;
447447

448448
// Create a program from the kernel source
449449
cl::Program program( QgsOpenClUtils::buildProgram( programTemplate, QgsOpenClUtils::ExceptionBehavior::Throw ) );
450450

451451
// Create the buffers, output is float32 (4 bytes)
452+
// We assume size of float = 4 because that's the size used by OpenCL and IEEE 754
453+
Q_ASSERT( sizeof( float ) == 4 );
452454
std::size_t resultBufferSize( 4 * static_cast<size_t>( mNumOutputColumns ) );
453455
cl::Buffer resultLineBuffer( ctx, CL_MEM_WRITE_ONLY,
454456
resultBufferSize, nullptr, nullptr );
@@ -461,7 +463,7 @@ QgsRasterCalculator::Result QgsRasterCalculator::processCalculationGPU( std::uni
461463
}
462464
kernel.setArg( static_cast<unsigned int>( inputBuffers.size() ), resultLineBuffer );
463465

464-
QgsOpenClUtils::CPLAllocator<float> resultLine( resultBufferSize );
466+
QgsOpenClUtils::CPLAllocator<float> resultLine( static_cast<size_t>( mNumOutputColumns ) );
465467

466468
//open output dataset for writing
467469
GDALDriverH outputDriver = openOutputDriver();
@@ -528,6 +530,7 @@ QgsRasterCalculator::Result QgsRasterCalculator::processCalculationGPU( std::uni
528530
// qDebug() << "Input: " << line << i << ref.varName << " = " << block->value( 0, i );
529531
//qDebug() << "Writing buffer " << ref.index;
530532

533+
Q_ASSERT( ref.bufferSize == static_cast<size_t>( block->data().size( ) ) );
531534
queue.enqueueWriteBuffer( inputBuffers[ref.index], CL_TRUE, 0,
532535
ref.bufferSize, block->bits() );
533536

‎tests/src/analysis/testqgsrastercalculator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,9 +679,9 @@ void TestQgsRasterCalculator::toString()
679679
QCOMPARE( _test( QStringLiteral( "\"raster@1\" + 2" ), false ), QString( "\"raster@1\" + 2" ) );
680680
QCOMPARE( _test( QStringLiteral( "\"raster@1\" + 2" ), true ), QString( "\"raster@1\" + 2" ) );
681681
QCOMPARE( _test( QStringLiteral( "\"raster@1\" ^ 3 + 2" ), false ), QString( "\"raster@1\"^3 + 2" ) );
682-
QCOMPARE( _test( QStringLiteral( "\"raster@1\" ^ 3 + 2" ), true ), QString( "pow( \"raster@1\", 3 ) + 2" ) );
682+
QCOMPARE( _test( QStringLiteral( "\"raster@1\" ^ 3 + 2" ), true ), QString( "pow( (float) ( \"raster@1\" ), (float) ( 3 ) ) + 2" ) );
683683
QCOMPARE( _test( QStringLiteral( "atan(\"raster@1\") * cos( 3 + 2 )" ), false ), QString( "atan( \"raster@1\" ) * cos( 3 + 2 )" ) );
684-
QCOMPARE( _test( QStringLiteral( "atan(\"raster@1\") * cos( 3 + 2 )" ), true ), QString( "atan( \"raster@1\" ) * cos( 3 + 2 )" ) );
684+
QCOMPARE( _test( QStringLiteral( "atan(\"raster@1\") * cos( 3 + 2 )" ), true ), QString( "atan( (float) ( \"raster@1\" ) ) * cos( (float) ( 3 + 2 ) )" ) );
685685
}
686686

687687

0 commit comments

Comments
 (0)
Please sign in to comment.