Skip to content

Commit 0c3cb68

Browse files
committed
Working but crashing on dealloc of command queue
1 parent 05be622 commit 0c3cb68

File tree

2 files changed

+145
-133
lines changed

2 files changed

+145
-133
lines changed

src/analysis/raster/qgsninecellfilter.cpp

Lines changed: 34 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "qgsfeedback.h"
2222
#include "qgsogrutils.h"
2323
#include <QFile>
24-
#include "qdebug.h"
24+
#include <QFileInfo>
2525

2626
#ifdef HAVE_OPENCL
2727
#ifdef __APPLE__
@@ -128,128 +128,25 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
128128
cl_mem outputNodataValue_mem_obj = clCreateBuffer( context, CL_MEM_READ_ONLY,
129129
sizeof( float ), NULL, &ret );
130130
cl_mem zFactor_mem_obj = clCreateBuffer( context, CL_MEM_READ_ONLY,
131-
sizeof( float ), NULL, &ret );
131+
sizeof( double ), NULL, &ret );
132132
cl_mem cellSizeX_mem_obj = clCreateBuffer( context, CL_MEM_READ_ONLY,
133-
sizeof( float ), NULL, &ret );
133+
sizeof( double ), NULL, &ret );
134134
cl_mem cellSizeY_mem_obj = clCreateBuffer( context, CL_MEM_READ_ONLY,
135-
sizeof( float ), NULL, &ret );
135+
sizeof( double ), NULL, &ret );
136136

137137
cl_mem resultLine_mem_obj = clCreateBuffer( context, CL_MEM_WRITE_ONLY,
138138
sizeof( float ) * xSize, NULL, &ret );
139139

140140

141-
const char *source_str = R"pgm(
142-
143-
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
144-
145-
float calcFirstDer( float x11, float x21, float x31, float x12, float x22, float x32, float x13, float x23, float x33,
146-
float mInputNodataValue, float mOutputNodataValue, float mZFactor, float mCellSize )
147-
{
148-
//the basic formula would be simple, but we need to test for nodata values...
149-
//X: return (( (x31 - x11) + 2 * (x32 - x12) + (x33 - x13) ) / (8 * mCellSizeX));
150-
//Y: return (((x11 - x13) + 2 * (x21 - x23) + (x31 - x33)) / ( 8 * mCellSizeY));
151-
152-
int weight = 0;
153-
double sum = 0;
154-
155-
//first row
156-
if ( x31 != mInputNodataValue && x11 != mInputNodataValue ) //the normal case
157-
{
158-
sum += ( x31 - x11 );
159-
weight += 2;
160-
}
161-
else if ( x31 == mInputNodataValue && x11 != mInputNodataValue && x21 != mInputNodataValue ) //probably 3x3 window is at the border
162-
{
163-
sum += ( x21 - x11 );
164-
weight += 1;
165-
}
166-
else if ( x11 == mInputNodataValue && x31 != mInputNodataValue && x21 != mInputNodataValue ) //probably 3x3 window is at the border
167-
{
168-
sum += ( x31 - x21 );
169-
weight += 1;
170-
}
171-
172-
//second row
173-
if ( x32 != mInputNodataValue && x12 != mInputNodataValue ) //the normal case
174-
{
175-
sum += 2 * ( x32 - x12 );
176-
weight += 4;
177-
}
178-
else if ( x32 == mInputNodataValue && x12 != mInputNodataValue && x22 != mInputNodataValue )
179-
{
180-
sum += 2 * ( x22 - x12 );
181-
weight += 2;
182-
}
183-
else if ( x12 == mInputNodataValue && x32 != mInputNodataValue && x22 != mInputNodataValue )
184-
{
185-
sum += 2 * ( x32 - x22 );
186-
weight += 2;
187-
}
188-
189-
//third row
190-
if ( x33 != mInputNodataValue && x13 != mInputNodataValue ) //the normal case
191-
{
192-
sum += ( x33 - x13 );
193-
weight += 2;
194-
}
195-
else if ( x33 == mInputNodataValue && x13 != mInputNodataValue && x23 != mInputNodataValue )
196-
{
197-
sum += ( x23 - x13 );
198-
weight += 1;
199-
}
200-
else if ( x13 == mInputNodataValue && x33 != mInputNodataValue && x23 != mInputNodataValue )
201-
{
202-
sum += ( x33 - x23 );
203-
weight += 1;
204-
}
205-
206-
if ( weight == 0 )
207-
{
208-
return mOutputNodataValue;
209-
}
210-
211-
return sum / ( weight * mCellSize ) * mZFactor;
212-
}
213-
214-
215-
__kernel void processNineCellWindow( __global float *scanLine1,
216-
__global float *scanLine2,
217-
__global float *scanLine3,
218-
__global float *resultLine,
219-
__global float *mInputNodataValue,
220-
__global float *mOutputNodataValue,
221-
__global float *mZFactor,
222-
__global float *mCellSizeX,
223-
__global float *mCellSizeY
224-
) {
225-
226-
// Get the index of the current element
227-
int i = get_global_id(0);
228-
229-
// Do the operation
230-
//return (( (x31 - x11) + 2 * (x32 - x12) + (x33 - x13) ) / (8 * mCellSizeX))
231-
float derX = calcFirstDer( scanLine1[i], scanLine2[i], scanLine3[i],
232-
scanLine1[i+1], scanLine2[i+1], scanLine3[i+1],
233-
scanLine1[i+2], scanLine2[i+2], scanLine3[i+2],
234-
*mInputNodataValue, *mOutputNodataValue, *mZFactor, *mCellSizeX
235-
);
236-
//return (((x11 - x13) + 2 * (x21 - x23) + (x31 - x33)) / ( 8 * mCellSizeY));
237-
float derY = calcFirstDer( scanLine1[i+2], scanLine1[i+1], scanLine1[i],
238-
scanLine2[i+2], scanLine2[i+1], scanLine2[i],
239-
scanLine3[i+2], scanLine3[i+1], scanLine3[i],
240-
*mInputNodataValue, *mOutputNodataValue, *mZFactor, *mCellSizeY
241-
);
242-
243-
if ( derX == *mOutputNodataValue || derY == *mOutputNodataValue )
244-
{
245-
resultLine[i] = *mOutputNodataValue;
246-
}
247-
else
248-
{
249-
resultLine[i] = atan( sqrt( derX * derX + derY * derY ) ) * 180.0 / M_PI;
250-
}
251-
}
252-
)pgm";
141+
char *source_str = new char [QFileInfo( "/home/ale/dev/QGIS/src/analysis/raster/slope.cl" ).size() + 1];
142+
143+
QFile file( "/home/ale/dev/QGIS/src/analysis/raster/slope.cl" );
144+
file.open( QIODevice::ReadOnly | QIODevice::Text );
145+
146+
file.read( source_str, file.size() );
147+
source_str[QFileInfo( "/home/ale/dev/QGIS/src/analysis/raster/slope.cl" ).size()] = '\0';
148+
file.close();
149+
253150
// Create a program from the kernel source
254151

255152
Q_ASSERT( ret == 0 );
@@ -272,10 +169,16 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
272169
program_log[log_size] = '\0';
273170
clGetProgramBuildInfo( program, device_id, CL_PROGRAM_BUILD_LOG,
274171
log_size + 1, program_log, NULL );
275-
qDebug() << program_log;
172+
QgsDebugMsgLevel( QStringLiteral( "Error building OpenCL program: %1" ).arg( program_log ), 1 );
276173
free( program_log );
277174
}
278175

176+
177+
// Create the OpenCL kernel
178+
cl_kernel kernel = clCreateKernel( program, "processNineCellWindow", &ret );
179+
180+
Q_ASSERT( ret == 0 );
181+
279182
#endif
280183

281184

@@ -329,7 +232,7 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
329232
QgsDebugMsg( "Raster IO Error" );
330233
}
331234
}
332-
235+
// Set first and last extra colums to nodata
333236
scanLine1[0] = scanLine1[xSize + 1] = mInputNodataValue;
334237
scanLine2[0] = scanLine2[xSize + 1] = mInputNodataValue;
335238
scanLine3[0] = scanLine3[xSize + 1] = mInputNodataValue;
@@ -348,17 +251,12 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
348251
ret = clEnqueueWriteBuffer( command_queue, outputNodataValue_mem_obj, CL_TRUE, 0,
349252
sizeof( float ), &mOutputNodataValue, 0, NULL, NULL );
350253
ret = clEnqueueWriteBuffer( command_queue, zFactor_mem_obj, CL_TRUE, 0,
351-
sizeof( float ), &mZFactor, 0, NULL, NULL );
254+
sizeof( double ), &mZFactor, 0, NULL, NULL );
352255
ret = clEnqueueWriteBuffer( command_queue, cellSizeX_mem_obj, CL_TRUE, 0,
353-
sizeof( float ), &mCellSizeX, 0, NULL, NULL );
256+
sizeof( double ), &mCellSizeX, 0, NULL, NULL );
354257
ret = clEnqueueWriteBuffer( command_queue, cellSizeY_mem_obj, CL_TRUE, 0,
355-
sizeof( float ), &mCellSizeY, 0, NULL, NULL );
356-
357-
358-
// Create the OpenCL kernel
359-
cl_kernel kernel = clCreateKernel( program, "processNineCellWindow", &ret );
258+
sizeof( double ), &mCellSizeY, 0, NULL, NULL );
360259

361-
Q_ASSERT( ret == 0 );
362260

363261
// Set the arguments of the kernel
364262
ret = ret || clSetKernelArg( kernel, 0, sizeof( cl_mem ), ( void * )&scanLine1_mem_obj );
@@ -392,20 +290,22 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
392290
QgsDebugMsg( "Raster IO Error" );
393291
}
394292

395-
qDebug() << resultLine[1];
396-
397-
ret = clReleaseKernel( kernel );
398-
399293
}
400294

401295
// Clean up
402-
ret = clFlush( command_queue );
403-
ret = clFinish( command_queue );
296+
//ret = clFlush( command_queue );
297+
//ret = clFinish( command_queue );
298+
ret = clReleaseKernel( kernel );
404299
ret = clReleaseProgram( program );
405300
ret = clReleaseMemObject( scanLine1_mem_obj );
406301
ret = clReleaseMemObject( scanLine2_mem_obj );
407302
ret = clReleaseMemObject( scanLine3_mem_obj );
408303
ret = clReleaseMemObject( resultLine_mem_obj );
304+
ret = clReleaseMemObject( inputNodataValue_mem_obj );
305+
ret = clReleaseMemObject( outputNodataValue_mem_obj );
306+
ret = clReleaseMemObject( zFactor_mem_obj );
307+
ret = clReleaseMemObject( cellSizeX_mem_obj );
308+
ret = clReleaseMemObject( cellSizeY_mem_obj );
409309
ret = clReleaseCommandQueue( command_queue );
410310
ret = clReleaseContext( context );
411311

@@ -427,12 +327,13 @@ int QgsNineCellFilter::processRaster( QgsFeedback *feedback )
427327
}
428328
#endif
429329

430-
431330
CPLFree( resultLine );
432331
CPLFree( scanLine1 );
433332
CPLFree( scanLine2 );
434333
CPLFree( scanLine3 );
435334

335+
delete source_str;
336+
436337
if ( feedback && feedback->isCanceled() )
437338
{
438339
//delete the dataset without closing (because it is faster)

src/analysis/raster/slope.cl

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
2+
3+
float calcFirstDer( float x11, float x21, float x31, float x12, float x22, float x32, float x13, float x23, float x33,
4+
float mInputNodataValue, float mOutputNodataValue, double mZFactor, double mCellSize )
5+
{
6+
//the basic formula would be simple, but we need to test for nodata values...
7+
//X: return (( (x31 - x11) + 2 * (x32 - x12) + (x33 - x13) ) / (8 * mCellSizeX));
8+
//Y: return (((x11 - x13) + 2 * (x21 - x23) + (x31 - x33)) / ( 8 * mCellSizeY));
9+
10+
int weight = 0;
11+
double sum = 0;
12+
13+
14+
//first row
15+
if ( x31 != mInputNodataValue && x11 != mInputNodataValue ) //the normal case
16+
{
17+
sum += ( x31 - x11 );
18+
weight += 2;
19+
}
20+
else if ( x31 == mInputNodataValue && x11 != mInputNodataValue && x21 != mInputNodataValue ) //probably 3x3 window is at the border
21+
{
22+
sum += ( x21 - x11 );
23+
weight += 1;
24+
}
25+
else if ( x11 == mInputNodataValue && x31 != mInputNodataValue && x21 != mInputNodataValue ) //probably 3x3 window is at the border
26+
{
27+
sum += ( x31 - x21 );
28+
weight += 1;
29+
}
30+
31+
//second row
32+
if ( x32 != mInputNodataValue && x12 != mInputNodataValue ) //the normal case
33+
{
34+
sum += 2.0f * ( x32 - x12 );
35+
weight += 4;
36+
}
37+
else if ( x32 == mInputNodataValue && x12 != mInputNodataValue && x22 != mInputNodataValue )
38+
{
39+
sum += 2.0f * ( x22 - x12 );
40+
weight += 2;
41+
}
42+
else if ( x12 == mInputNodataValue && x32 != mInputNodataValue && x22 != mInputNodataValue )
43+
{
44+
sum += 2.0f * ( x32 - x22 );
45+
weight += 2;
46+
}
47+
48+
//third row
49+
if ( x33 != mInputNodataValue && x13 != mInputNodataValue ) //the normal case
50+
{
51+
sum += ( x33 - x13 );
52+
weight += 2;
53+
}
54+
else if ( x33 == mInputNodataValue && x13 != mInputNodataValue && x23 != mInputNodataValue )
55+
{
56+
sum += ( x23 - x13 );
57+
weight += 1;
58+
}
59+
else if ( x13 == mInputNodataValue && x33 != mInputNodataValue && x23 != mInputNodataValue )
60+
{
61+
sum += ( x33 - x23 );
62+
weight += 1;
63+
}
64+
65+
if ( weight == 0 )
66+
{
67+
return mOutputNodataValue;
68+
}
69+
70+
return sum / ( weight * mCellSize ) * mZFactor;
71+
}
72+
73+
74+
__kernel void processNineCellWindow( __global float *scanLine1,
75+
__global float *scanLine2,
76+
__global float *scanLine3,
77+
__global float *resultLine,
78+
__global float *mInputNodataValue,
79+
__global float *mOutputNodataValue,
80+
__global double *mZFactor,
81+
__global double *mCellSizeX,
82+
__global double *mCellSizeY
83+
) {
84+
85+
// Get the index of the current element
86+
int i = get_global_id(0);
87+
88+
// Do the operation
89+
//return (( (x31 - x11) + 2 * (x32 - x12) + (x33 - x13) ) / (8 * mCellSizeX))
90+
float derX = calcFirstDer( scanLine1[i], scanLine2[i], scanLine3[i],
91+
scanLine1[i+1], scanLine2[i+1], scanLine3[i+1],
92+
scanLine1[i+2], scanLine2[i+2], scanLine3[i+2],
93+
*mInputNodataValue, *mOutputNodataValue, *mZFactor, *mCellSizeX
94+
);
95+
//return (((x11 - x13) + 2 * (x21 - x23) + (x31 - x33)) / ( 8 * mCellSizeY));
96+
float derY = calcFirstDer( scanLine1[i+2], scanLine1[i+1], scanLine1[i],
97+
scanLine2[i+2], scanLine2[i+1], scanLine2[i],
98+
scanLine3[i+2], scanLine3[i+1], scanLine3[i],
99+
*mInputNodataValue, *mOutputNodataValue, *mZFactor, *mCellSizeY
100+
);
101+
if ( derX == *mOutputNodataValue || derY == *mOutputNodataValue )
102+
{
103+
resultLine[i] = *mOutputNodataValue;
104+
}
105+
else
106+
{
107+
double res = sqrt( derX * derX + derY * derY );
108+
res = atanpi( res );
109+
resultLine[i] = (float)res * 180.0;
110+
}
111+
}

0 commit comments

Comments
 (0)