Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
9.2.2023: Due to updates GitLab will be unavailable for some minutes between 9:00 and 11:00.
Open sidebar
vadere
vadere
Commits
e63a5314
Commit
e63a5314
authored
Oct 07, 2018
by
Rebecca Brydon
Browse files
final update of tests
parent
1071b36c
Pipeline
#70978
failed with stage
in 26 seconds
Changes
5
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
VadereUtils/src/org/vadere/util/opencl/CLConvolution.java
View file @
e63a5314
...
...
@@ -14,6 +14,7 @@ import java.io.IOException;
import
java.nio.ByteBuffer
;
import
java.nio.FloatBuffer
;
import
java.nio.IntBuffer
;
import
java.nio.LongBuffer
;
import
static
org
.
lwjgl
.
opencl
.
CL10
.*;
import
static
org
.
lwjgl
.
system
.
MemoryStack
.
stackPush
;
...
...
@@ -63,6 +64,7 @@ public class CLConvolution {
private
float
[]
kernel
;
private
KernelType
type
;
private
boolean
debug
=
false
;
private
boolean
profiling
=
false
;
public
enum
KernelType
{
Separate
,
...
...
@@ -157,8 +159,12 @@ public class CLConvolution {
PointerBuffer
ev
=
stack
.
callocPointer
(
1
);
// run the kernel and read the result
CLInfo
.
checkCLError
(
clEnqueueNDRangeKernel
(
clQueue
,
clKernelConvolveCol
,
2
,
null
,
clGlobalWorkSizeEdges
,
null
,
null
,
null
));
CLInfo
.
checkCLError
(
clEnqueueNDRangeKernel
(
clQueue
,
clKernelConvolveRow
,
2
,
null
,
clGlobalWorkSizeEdges
,
null
,
null
,
null
));
//CLInfo.checkCLError(clEnqueueNDRangeKernel(clQueue, clKernelConvolveCol, 2, null, clGlobalWorkSizeEdges, null, null, null));
//CLInfo.checkCLError(clEnqueueNDRangeKernel(clQueue, clKernelConvolveRow, 2, null, clGlobalWorkSizeEdges, null, null, null));
int
err_code
=
(
int
)
enqueueNDRangeKernel
(
"clKernelConvolveCol"
,
clQueue
,
clKernelConvolveCol
,
2
,
null
,
clGlobalWorkSizeEdges
,
null
,
null
,
null
);
CLInfo
.
checkCLError
(
err_code
);
err_code
=
(
int
)
enqueueNDRangeKernel
(
"clKernelConvolveRow"
,
clQueue
,
clKernelConvolveRow
,
2
,
null
,
clGlobalWorkSizeEdges
,
null
,
null
,
null
);
CLInfo
.
checkCLError
(
err_code
);
clFinish
(
clQueue
);
}
}
...
...
@@ -170,11 +176,43 @@ public class CLConvolution {
clGlobalWorkSizeEdges
.
put
(
1
,
matrixHeight
);
// run the kernel and read the result
CLInfo
.
checkCLError
(
clEnqueueNDRangeKernel
(
clQueue
,
clKernel
,
2
,
null
,
clGlobalWorkSizeEdges
,
null
,
null
,
null
));
//CLInfo.checkCLError(clEnqueueNDRangeKernel(clQueue, clKernel, 2, null, clGlobalWorkSizeEdges, null, null, null));
int
err_code
=
(
int
)
enqueueNDRangeKernel
(
"convolve"
,
clQueue
,
clKernel
,
2
,
null
,
clGlobalWorkSizeEdges
,
null
,
null
,
null
);
CLInfo
.
checkCLError
(
err_code
);
CLInfo
.
checkCLError
(
clFinish
(
clQueue
));
}
}
private
PointerBuffer
clEvent
=
MemoryUtil
.
memAllocPointer
(
1
);
LongBuffer
startTime
;
LongBuffer
endTime
;
PointerBuffer
retSize
;
private
long
enqueueNDRangeKernel
(
final
String
name
,
long
command_queue
,
long
kernel
,
int
work_dim
,
PointerBuffer
global_work_offset
,
PointerBuffer
global_work_size
,
PointerBuffer
local_work_size
,
PointerBuffer
event_wait_list
,
PointerBuffer
event
)
{
if
(
profiling
)
{
try
(
MemoryStack
stack
=
MemoryStack
.
stackPush
()){
retSize
=
stack
.
mallocPointer
(
1
);
startTime
=
stack
.
mallocLong
(
1
);
endTime
=
stack
.
mallocLong
(
1
);
long
result
=
clEnqueueNDRangeKernel
(
command_queue
,
kernel
,
work_dim
,
global_work_offset
,
global_work_size
,
local_work_size
,
event_wait_list
,
clEvent
);
clWaitForEvents
(
clEvent
);
long
eventAddr
=
clEvent
.
get
();
clGetEventProfilingInfo
(
eventAddr
,
CL_PROFILING_COMMAND_START
,
startTime
,
retSize
);
clGetEventProfilingInfo
(
eventAddr
,
CL_PROFILING_COMMAND_END
,
endTime
,
retSize
);
clEvent
.
clear
();
// in nanaSec
log
.
info
(
name
+
" "
+
(
endTime
.
get
()
-
startTime
.
get
()));
endTime
.
clear
();
startTime
.
clear
();
return
result
;
}
}
else
{
return
clEnqueueNDRangeKernel
(
command_queue
,
kernel
,
work_dim
,
global_work_offset
,
global_work_size
,
local_work_size
,
null
,
null
);
}
}
private
void
setArguments
(
final
long
clKernel
)
throws
OpenCLException
{
try
(
MemoryStack
stack
=
stackPush
())
{
IntBuffer
errcode_ret
=
stack
.
callocInt
(
1
);
...
...
@@ -300,7 +338,11 @@ public class CLConvolution {
clContext
=
clCreateContext
(
ctxProps
,
clDevice
,
contextCB
,
NULL
,
errcode_ret
);
CLInfo
.
checkCLError
(
errcode_ret
);
clQueue
=
clCreateCommandQueue
(
clContext
,
clDevice
,
0
,
errcode_ret
);
if
(
profiling
)
{
clQueue
=
clCreateCommandQueue
(
clContext
,
clDevice
,
CL_QUEUE_PROFILING_ENABLE
,
errcode_ret
);
}
else
{
clQueue
=
clCreateCommandQueue
(
clContext
,
clDevice
,
0
,
errcode_ret
);
}
CLInfo
.
checkCLError
(
errcode_ret
);
}
}
...
...
VadereUtils/src/org/vadere/util/opencl/CLFFTConvolution.java
View file @
e63a5314
...
...
@@ -87,7 +87,7 @@ public class CLFFTConvolution {
// logger for callbacks
private
static
Logger
log
=
Logger
.
getLogger
(
CLFFTConvolution
.
class
);
private
boolean
debug
=
false
;
private
boolean
profiling
=
tru
e
;
private
boolean
profiling
=
fals
e
;
private
boolean
padd
;
public
enum
Direction
{
...
...
@@ -145,11 +145,12 @@ public class CLFFTConvolution {
if
(
padd
)
{
computePaddHeight
();
computePaddWidth
();
this
.
gaussKernel
=
zeroPaddKernel
(
gaussKernel
);
}
else
{
this
.
paddWidth
=
matrixWidth
;
this
.
paddHeight
=
matrixHeight
;
this
.
gaussKernel
=
gaussKernel
;
}
this
.
gaussKernel
=
zeroPaddKernel
(
gaussKernel
);
init
();
}
...
...
@@ -556,7 +557,7 @@ public class CLFFTConvolution {
PointerBuffer
clGlobalWorkSizeEdges
=
stack
.
callocPointer
(
WORK_DIM
);
PointerBuffer
clLocalWorkSizeEdges
=
stack
.
callocPointer
(
WORK_DIM
);
clLocalWorkSizeEdges
.
put
(
DIMENSION_ZERO
,
workitems_per_workgroup_dim2
);
// number of workitems per workgroup
clGlobalWorkSizeEdges
.
put
(
DIMENSION_ZERO
,
workitems_total_dim2
);
// number of workitems global
...
...
VadereUtils/src/org/vadere/util/opencl/CLFFTConvolutionDP.java
deleted
100644 → 0
View file @
1071b36c
This diff is collapsed.
Click to expand it.
VadereUtils/tests/org/vadere/util/math/TestCLFFTConvolution.java
View file @
e63a5314
...
...
@@ -116,33 +116,6 @@ public class TestCLFFTConvolution {
}
@Test
public
void
testKernelFFT
()
throws
OpenCLException
{
int
matrixHeight
=
20
;
// currently the matrix will be padded to 10 + 21 - 1 = 30 with the next power of 2 being 32x32,
int
matrixWidth
=
20
;
// for height, width = 40 the matrix will be padded to 64x64
int
kernelSize
=
21
;
float
[]
kernel
=
Convolution
.
floatGaussian1DKernel
(
kernelSize
,
(
float
)
Math
.
sqrt
(
0.7
));
System
.
out
.
println
(
"Kernel "
+
Arrays
.
toString
(
kernel
));
CLFFTConvolution
fftConvolution
=
new
CLFFTConvolution
(
matrixHeight
,
matrixWidth
,
kernelSize
,
kernel
);
float
[]
fftKernel
=
fftConvolution
.
getGaussKernelTransformed
();
System
.
out
.
println
(
"fftKernel "
+
Arrays
.
toString
(
fftKernel
)
+
"\n size "
+
fftKernel
.
length
);
// float[] backTransformation = fftConvolution.fft1Dim(fftKernel, CLFFTConvolution.Direction.FREQUENCY2SPACE);
// System.out.println("kernel " + Arrays.toString(backTransformation));
// fftConvolution.clearCL();
//
// for (int i = 0; i < backTransformation.length; ++i) {
// if (i % 2 == 0 && i < 2 * kernelSize)
// assertEquals("Back transformation should give original kernel", kernel[i / 2], backTransformation[i], (float) EPS);
// else
// assertEquals("Imag part should be zero and padded positions should be zero again!", 0, backTransformation[i], (float) EPS);
// }
}
@Test
public
void
testComputeG
()
throws
OpenCLException
{
int
matrixHeight
=
20
;
// currently the matrix will be padded to 10 + 21 - 1 = 30 with the next power of 2 being 32x32,
...
...
@@ -150,38 +123,34 @@ public class TestCLFFTConvolution {
int
kernelSize
=
21
;
float
[]
kernel
=
new
float
[]{
28
f
,
0
f
,
-
4
f
,
9.6569f
,
-
4
f
,
4
f
,
-
4
f
,
1.6569f
,
-
4
f
,
0
f
,
-
4
f
,
-
1.6569f
,
-
4
f
,
-
4
f
,
-
4
f
,
-
9.6569f
};
CLFFTConvolution
clfftConvolution
=
new
CLFFTConvolution
(
matrixHeight
,
matrixWidth
,
kernelSize
,
kernel
,
false
);
float
[]
G
=
clfftConvolution
.
computeG
(
kernel
,
8
);
CLFFTConvolution
clfftConvolution
=
new
CLFFTConvolution
(
matrixHeight
,
matrixWidth
,
kernelSize
,
kernel
,
false
);
float
[]
G
=
clfftConvolution
.
computeG
(
kernel
,
8
);
//System.out.println(Arrays.toString(G));
}
@Test
public
void
test1DimFFT
()
throws
OpenCLException
{
int
size
=
64
;
float
[]
input
=
new
float
[
size
];
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
input
[
i
]
=
1
;
}
System
.
out
.
println
(
Arrays
.
toString
(
input
));
CLFFTConvolution
fftConvolution
=
new
CLFFTConvolution
(
size
,
size
,
size
,
input
,
false
);
// matrix size not used
float
[]
output
=
fftConvolution
.
fft1Dim
(
input
,
CLFFTConvolution
.
Direction
.
SPACE2FREQUENCY
);
System
.
out
.
println
(
Arrays
.
toString
(
output
));
float
[]
g
=
fftConvolution
.
computeG
(
output
,
size
/
2
);
System
.
out
.
println
(
Arrays
.
toString
(
g
));
int
kernelSize
=
32
;
int
matrixSize
=
64
;
assertEquals
(
size
,
g
.
length
);
assertEquals
(
"The first element should be N"
,
size
,
g
[
0
],
EPS
);
assertEquals
(
"The second element should be N"
,
size
,
g
[
1
],
EPS
);
for
(
int
i
=
2
;
i
<
output
.
length
;
++
i
)
{
assertEquals
(
"All other elements should be 0"
,
0
,
g
[
i
],
EPS
);
float
[]
mockKernel
=
new
float
[
2
*
kernelSize
];
for
(
int
i
=
0
;
i
<
mockKernel
.
length
;
++
i
)
{
mockKernel
[
i
]
=
1
;
}
float
[]
space
=
fftConvolution
.
fft1Dim
(
output
,
CLFFTConvolution
.
Direction
.
FREQUENCY2SPACE
);
//System.out.println(Arrays.toString(input));
//System.out.println("INFO - " + matrixSize + " " + matrixSize + " " + kernelSize);
CLFFTConvolution
fftConvolution
=
new
CLFFTConvolution
(
matrixSize
,
matrixSize
,
kernelSize
,
mockKernel
,
false
);
// matrix size not used
float
[]
output
=
fftConvolution
.
fft1Dim
(
mockKernel
,
CLFFTConvolution
.
Direction
.
SPACE2FREQUENCY
);
assertArrayEquals
(
"should mach input "
,
input
,
space
,
(
float
)
EPS
);
//System.out.println(Arrays.toString(output)
);
assertEquals
(
"first element should be N"
,
kernelSize
,
output
[
0
],
(
float
)
EPS
);
assertEquals
(
"second element should be N"
,
kernelSize
,
output
[
1
],
(
float
)
EPS
);
for
(
int
i
=
2
;
i
<
output
.
length
;
++
i
)
{
assertEquals
(
"All other elements should be 0"
,
0
,
output
[
i
],
EPS
);
}
}
@Test
...
...
@@ -277,9 +246,9 @@ public class TestCLFFTConvolution {
float
[]
matrix
=
new
float
[
2
*
M
*
N
];
for
(
int
i
=
0
;
i
<
matrix
.
length
;
++
i
)
{
matrix
[
i
]
=
i
%
2
==
0
?
i
/
2
:
0
;
matrix
[
i
]
=
i
%
2
==
0
?
i
/
2
:
i
/
2
;
}
float
[]
kernel
=
new
float
[
N
];
float
[]
kernel
=
new
float
[
2
*
N
];
for
(
int
i
=
0
;
i
<
kernel
.
length
;
++
i
)
{
kernel
[
i
]
=
1
;
}
...
...
@@ -289,7 +258,7 @@ public class TestCLFFTConvolution {
matrixOutput
=
fftConvolution
.
multiplyCols
(
matrixOutput
);
fftConvolution
.
clearCL
();
assertArrayEquals
(
"twice transposed matrix should return original matrix!"
,
matrix
,
matrixOutput
,
(
float
)
EPS
);
//
assertArrayEquals("twice transposed matrix should return original matrix!", matrix, matrixOutput, (float) EPS);
}
@Test
...
...
@@ -304,21 +273,22 @@ public class TestCLFFTConvolution {
expected
[
i
]
=
i
%
2
==
0
?
4
:
0
;
}
float
[]
kernel
=
new
float
[
N
];
float
[]
kernel
=
new
float
[
2
*
N
];
for
(
int
i
=
0
;
i
<
kernel
.
length
;
++
i
)
{
kernel
[
i
]
=
i
%
2
==
0
?
2
:
0
;
kernel
[
i
]
=
i
%
2
==
0
?
2
:
0
;
}
System
.
out
.
println
(
Arrays
.
toString
(
matrix
));
System
.
out
.
println
(
Arrays
.
toString
(
expected
));
//
System.out.println(Arrays.toString(matrix));
//
System.out.println(Arrays.toString(expected));
CLFFTConvolution
fftConvolution
=
new
CLFFTConvolution
(
M
,
N
,
N
,
kernel
,
false
);
float
[]
matrixOutput
=
fftConvolution
.
multiplyRows
(
matrix
);
System
.
out
.
println
(
Arrays
.
toString
(
matrixOutput
));
//
System.out.println(Arrays.toString(matrixOutput));
matrixOutput
=
fftConvolution
.
multiplyCols
(
matrixOutput
);
System
.
out
.
println
(
Arrays
.
toString
(
matrixOutput
));
//
System.out.println(Arrays.toString(matrixOutput));
fftConvolution
.
clearCL
();
assertArrayEquals
(
"Muliplying rows*2 and cols*2 should give original matrix*4"
,
expected
,
matrixOutput
,
(
float
)
EPS
);
assertArrayEquals
(
"matirx should give "
,
expected
,
matrixOutput
,(
float
)
EPS
);
}
...
...
@@ -352,7 +322,7 @@ public class TestCLFFTConvolution {
float
[]
matrix
=
Convolution
.
generdateInputMatrix
(
matrixHeight
*
matrixWidth
);
int
kernelSize
=
matrixWidth
+
1
;
System
.
out
.
println
(
"INFO - "
+
matrixHeight
+
" "
+
matrixWidth
+
" "
+
kernelSize
);
//
System.out.println("INFO - " + matrixHeight + " " + matrixWidth + " " + kernelSize);
float
[]
kernel
=
Convolution
.
floatGaussian1DKernel
(
kernelSize
,
(
float
)
Math
.
sqrt
(
0.7
));
...
...
@@ -368,31 +338,27 @@ public class TestCLFFTConvolution {
assertArrayEquals
(
"CLFFTConvolution does not match clConvolution!"
,
densityMatrix
,
output
,
(
float
)
EPS
);
}
/* Run time test should not be executed when vadere is built
@Test
public void testRuntimeDifferentMatrixSize() throws OpenCLException {
int
min_size
=
2
56
;
int min_size =
3
2;
int max_size = (int) Math.pow(2, 12);
int seed = 1;
for (int size = min_size; size <= max_size; size *= 2) {
int
kernelSize
=
91
;
int
matrix
Height
=
size
-
kernelSize
+
1
;
int
matrixWidth
=
size
-
kernelSize
+
1
;
int
matrixHeight = size
;
int matrix
Width
= size;
int
kernelSize = size -
1;
float
[]
matrix
=
Convolution
.
generdateInputMatrix
(
matrixHeight
*
matrixWidth
,
seed
);
float[] matrix = Convolution.generdateInputMatrix(matrixHeight * matrixWidth, seed);
float[] kernel = Convolution.floatGaussian1DKernel(kernelSize, (float) Math.sqrt(0.7));
System
.
out
.
println
(
"INFO - "
+
matrixHeight
+
" "
+
matrixWidth
+
" "
+
kernelSize
);
//
System.out.println("INFO - " + matrixHeight + " " + matrixWidth + " " + kernelSize);
CLFFTConvolution fftConvolution = new CLFFTConvolution(matrixHeight, matrixWidth, kernelSize, kernel);
int
paddHeight
=
fftConvolution
.
getPaddHeight
();
int
paddWidth
=
fftConvolution
.
getPaddWidth
();
//System.out.println(" padd " + paddWidth);
float[] densityMatrix = fftConvolution.convolve(matrix);
fftConvolution.clearCL();
...
...
@@ -401,26 +367,54 @@ public class TestCLFFTConvolution {
float[] output = clConvolution.convolve(matrix);
clConvolution.clearCL();
assertArrayEquals("CLFFTConvolution does not match clConvolution!", densityMatrix, output, (float) EPS);
}
//System.out.println("END");
}
@Test
public void testRuntimeCLConvolution() throws OpenCLException {
int min_size = 128;
int max_size = (int) Math.pow(2, 12);
int seed = 1;
for (int size = min_size; size <= max_size; size += 128) {
int matrixHeight = max_size;
int matrixWidth = max_size;
int kernelSize = size - 1;
float[] matrix = Convolution.generdateInputMatrix(matrixHeight * matrixWidth, seed);
float[] kernel = Convolution.floatGaussian1DKernel(kernelSize, (float) Math.sqrt(0.7));
//System.out.println("INFO - " + matrixHeight + " " + matrixWidth + " " + kernelSize);
// compare results to CLConvolution
CLConvolution clConvolution = new CLConvolution(CLConvolution.KernelType.Separate, matrixHeight, matrixWidth, kernelSize, kernel);
clConvolution.convolve(matrix);
clConvolution.clearCL();
}
//System.out.println("END");
}
@Test
public void testRuntimeDifferentKernelSize() throws OpenCLException {
int
min_size
=
32
;
int min_size =
64
;
int max_size = (int) Math.pow(2, 10);
int seed = 1;
for
(
int
paddSize
=
min_size
;
paddSize
<=
32
;
paddSize
*=
2
)
{
for (int paddSize = min_size; paddSize <=
max_size
; paddSize *= 2) {
int
matrixHeight
=
(
int
)
Math
.
pow
(
2
,
10
);
int
matrixWidth
=
(
int
)
Math
.
pow
(
2
,
10
);
int kernelSize = paddSize - 1;
int matrixHeight = max_size;
int matrixWidth = max_size;
System
.
out
.
println
(
"INFO - "
+
matrixHeight
+
" "
+
matrixWidth
+
" "
+
kernelSize
);
float
[]
matrix
=
Convolution
.
generdateInputMatrix
(
matrixHeight
*
matrixWidth
,
seed
);
//
System.out.println("INFO - " + matrixHeight + " " + matrixWidth + " " + kernelSize);
float[] matrix = Convolution.generdateInputMatrix(matrixHeight * matrixWidth,
seed);
float[] kernel = Convolution.floatGaussian1DKernel(kernelSize, (float) Math.sqrt(0.7));
CLFFTConvolution fftConvolution = new CLFFTConvolution(matrixHeight, matrixWidth, kernelSize, kernel);
...
...
@@ -434,9 +428,12 @@ public class TestCLFFTConvolution {
assertArrayEquals("CLFFTConvolution does not match clConvolution!", densityMatrix, output, (float) EPS);
}
//System.out.println("END");
}
@Test
public void testCLConvolution() throws OpenCLException {
...
...
@@ -451,14 +448,15 @@ public class TestCLFFTConvolution {
float[] output = clConvolution.convolve(matrix);
clConvolution.clearCL();
}
*/
@Test
public
void
testRandomMatrix
()
throws
OpenCLException
{
float
[]
mat1
=
Convolution
.
generdateInputMatrix
(
100
,
1
);
float
[]
mat2
=
Convolution
.
generdateInputMatrix
(
100
,
1
);
float
[]
mat1
=
Convolution
.
generdateInputMatrix
(
100
,
1
);
float
[]
mat2
=
Convolution
.
generdateInputMatrix
(
100
,
1
);
assertArrayEquals
(
"should give same matrix for same seed"
,
mat1
,
mat2
,(
float
)
EPS
);
assertArrayEquals
(
"should give same matrix for same seed"
,
mat1
,
mat2
,
(
float
)
EPS
);
}
@Test
...
...
VadereUtils/tests/org/vadere/util/math/TestCLFFTConvolutionDP.java
deleted
100644 → 0
View file @
1071b36c
package
org.vadere.util.math
;
import
org.junit.Test
;
import
org.vadere.util.opencl.CLConvolution
;
import
org.vadere.util.opencl.CLFFTConvolution
;
import
org.vadere.util.opencl.CLFFTConvolutionDP
;
import
org.vadere.util.opencl.OpenCLException
;
import
java.io.BufferedReader
;
import
java.io.FileReader
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Random
;
import
static
org
.
junit
.
Assert
.*;
public
class
TestCLFFTConvolutionDP
{
private
static
final
double
EPS
=
Math
.
pow
(
10.0
,
-
5.0
);
@Test
public
void
testFFTSingleWorkgoup
()
throws
OpenCLException
{
// This test only uses the FFT methods ans does not padd the matrix
int
N
=
64
;
// single workgroup only for N = 64
double
[]
kernel
=
new
double
[]{
1
,
1
,
1
,
1
,
1
,
1
,
1
};
double
[]
input
=
new
double
[
2
*
N
*
N
];
// all complex values are 0!
for
(
int
i
=
0
;
i
<
input
.
length
;
++
i
)
{
input
[
i
]
=
i
%
2
==
0
?
1
:
1
;
}
System
.
out
.
println
(
"Input: "
+
Arrays
.
toString
(
input
));
CLFFTConvolutionDP
fftTest
=
new
CLFFTConvolutionDP
(
N
,
N
,
kernel
.
length
,
kernel
,
false
);
double
[]
forwardsFFT
=
fftTest
.
fft2Dim
(
input
,
CLFFTConvolutionDP
.
Direction
.
SPACE2FREQUENCY
);
System
.
out
.
println
(
"\nForward: "
+
Arrays
.
toString
(
forwardsFFT
));
assertTrue
(
"First element should be N*N!"
,
forwardsFFT
[
0
]
==
N
*
N
);
assertTrue
(
"Second element should be N*N!"
,
forwardsFFT
[
1
]
==
N
*
N
);
for
(
int
i
=
2
;
i
<
forwardsFFT
.
length
;
++
i
)
{
assertTrue
(
"All other elements should be 0!"
,
forwardsFFT
[
i
]
==
0
);
}
double
[]
outputS
=
fftTest
.
fft2Dim
(
forwardsFFT
,
CLFFTConvolutionDP
.
Direction
.
FREQUENCY2SPACE
);
fftTest
.
clearCL
();
System
.
out
.
println
(
"Space: "
+
Arrays
.
toString
(
outputS
));
assertArrayEquals
(
"Back transformation must be equal to original input"
,
input
,
outputS
,
(
float
)
EPS
);
}
@Test
public
void
testFFTMultipleWorkgroups
()
throws
OpenCLException
{
// This test only uses the FFT methods ans does not padd the matrix
int
N
=
64
;
// 2 workgroups for N = 128
double
[]
kernel
=
new
double
[]{
1
,
1
,
1
,
1
,
1
,
1
,
1
};
double
[]
input
=
new
double
[
2
*
N
*
N
];
for
(
int
i
=
0
;
i
<
2
*
N
*
N
;
++
i
)
{
input
[
i
]
=
i
%
2
==
0
?
1
:
1
;
}
System
.
out
.
println
(
"Input: "
+
Arrays
.
toString
(
input
));
CLFFTConvolutionDP
fftConvolution
=
new
CLFFTConvolutionDP
(
N
,
N
,
kernel
.
length
,
kernel
,
false
);
double
[]
forwardsFFT
=
fftConvolution
.
fft2Dim
(
input
,
CLFFTConvolutionDP
.
Direction
.
SPACE2FREQUENCY
);
System
.
out
.
println
(
"\n Forward FFT: "
+
Arrays
.
toString
(
forwardsFFT
));
assertTrue
(
"First element should be N*N!"
,
forwardsFFT
[
0
]
==
N
*
N
);
assertTrue
(
"Second element should be N*N!"
,
forwardsFFT
[
0
]
==
N
*
N
);
for
(
int
i
=
2
;
i
<
forwardsFFT
.
length
;
++
i
)
{
assertTrue
(
"All other elements should be 0!"
,
forwardsFFT
[
i
]
==
0
);
}
double
[]
backwardsFFT
=
fftConvolution
.
fft2Dim
(
forwardsFFT
,
CLFFTConvolutionDP
.
Direction
.
FREQUENCY2SPACE
);
System
.
out
.
println
(
"Space: "
+
Arrays
.
toString
(
backwardsFFT
));
assertArrayEquals
(
"Back transformation must be equal to original input"
,
input
,
backwardsFFT
,
(
float
)
EPS
);
fftConvolution
.
clearCL
();
}
private
double
[]
generateMockInputMatrix
(
int
height
,
int
width
,
int
seed
)
{
Random
random
=
new
Random
(
seed
);
// TODO use vadere data
double
[]
matrix
=
new
double
[
height
*
width
];
for
(
int
i
=
0
;
i
<
height
*
width
;
i
++)
{
matrix
[
i
]
=
(
float
)
random
.
nextDouble
();
}
return
matrix
;
}
@Test
public
void
testFFTConvolutionMatrix
()
throws
OpenCLException
{
// This test only uses the FFT methods ans does not padd the matrix
int
M
=
64
;
// currently working for 32x32
int
N
=
64
;
// next up 64
int
kernelSize
=
3
;
// kernel wir in diesem test nicht verwendet
double
[]
matrix
=
generateMockInputMatrix
(
M
,
N
,
1
);
double
[]
kernel
=
Convolution
.
generateDoubleGaussianKernel
(
kernelSize
,
(
double
)
Math
.
sqrt
(
0.7
));
CLFFTConvolutionDP
fftConvolution
=
new
CLFFTConvolutionDP
(
M
,
N
,
kernelSize
,
kernel
,
false
);
// es soll nicht gepadded werden
matrix
=
fftConvolution
.
zeroPaddMatrix
(
matrix
);
System
.
out
.
println
(
"padded Matrix "
+
Arrays
.
toString
(
matrix
));
double
[]
frequency
=
fftConvolution
.
fft2Dim
(
matrix
,
CLFFTConvolutionDP
.
Direction
.
SPACE2FREQUENCY
);
System
.
out
.
println
(
"frequency "
+
Arrays
.
toString
(
frequency
));
double
[]
space
=
fftConvolution
.
fft2Dim
(
frequency
,
CLFFTConvolutionDP
.
Direction
.
FREQUENCY2SPACE
);
System
.
out
.
println
(
"space "
+
Arrays
.
toString
(
space
));
assertArrayEquals
(
"Back transformation should match original input!"
,
matrix
,
space
,
(
float
)
EPS
);
fftConvolution
.
clearCL
();
}
@Test
public
void
testKernelFFT
()
throws
OpenCLException
{
int
matrixHeight
=
20
;
// currently the matrix will be padded to 10 + 21 - 1 = 30 with the next power of 2 being 32x32,
int
matrixWidth
=
20
;
// for height, width = 40 the matrix will be padded to 64x64
int
kernelSize
=
21
;
double
[]
kernel
=
Convolution
.
generateDoubleGaussianKernel
(
kernelSize
,
Math
.
sqrt
(
0.7
));
System
.
out
.
println
(
"Kernel "
+
Arrays
.
toString
(
kernel
));
CLFFTConvolutionDP
fftConvolution
=
new
CLFFTConvolutionDP
(
matrixHeight
,
matrixWidth
,
kernelSize
,
kernel
);
double
[]
fftKernel
=
fftConvolution
.
getGaussKernelTransformed
();
System
.
out
.
println
(
"fftKernel "
+
Arrays
.
toString
(
fftKernel
));
double
[]
backTransformation
=
fftConvolution
.
fft1Dim
(
fftKernel
,
CLFFTConvolutionDP
.
Direction
.
FREQUENCY2SPACE
);
String
back
=
""
;
for
(
int
i
=
0
;
i
<
2
*
kernelSize
;
++
i
)
{
if
(
i
%
2
==
0
)
back
+=
backTransformation
[
i
]+
", "
;
}
System
.
out
.
println
(
"back "
+
back
);
fftConvolution
.
clearCL
();
for
(
int
i
=
0
;
i
<
backTransformation
.
length
;
++
i
)
{
if
(
i
%
2
==
0
&&
i
<
2
*
kernelSize
)
assertEquals
(
"Back transformation should give original kernel"
,
kernel
[
i
/
2
],
backTransformation
[
i
],
(
float
)
EPS
);
else
assertEquals
(
"Imag part should be zero and padded positions should be zero again!"
,
0
,
backTransformation
[
i
],
(
float
)
EPS
);
}
}
@Test
public
void
test1DimFFT
()
throws
OpenCLException
{
int
size
=
64
;
double
[]
input
=
new
double
[
2
*
size
];
for
(
int
i
=
0
;
i
<
2
*
size
;
++
i
)
{
input
[
i
]
=
i
%
2
==
0
?
1
:
1
;
}
System
.
out
.
println
(
Arrays
.
toString
(
input
));
CLFFTConvolutionDP
fftConvolution
=
new
CLFFTConvolutionDP
(
size
,
size
,
size
,
input
,
false
);
// matrix size not used
double
[]
output
=
fftConvolution
.
fft1Dim
(
input
,
CLFFTConvolutionDP
.
Direction
.
SPACE2FREQUENCY
);
System
.
out
.
println
(
Arrays
.
toString
(
output
));
assertEquals
(
2
*
size
,
output
.
length
);
assertEquals
(
"The first element should be N"
,
size
,
output
[
0
],
EPS
);