Commit e63a5314 authored by Rebecca Brydon's avatar Rebecca Brydon
Browse files

final update of tests

parent 1071b36c
Pipeline #70978 failed with stage
in 26 seconds
......@@ -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);
}
}
......
......@@ -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 = true;
private boolean profiling = false;
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
......
......@@ -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[]{28f, 0f, -4f, 9.6569f, -4f, 4f, -4f, 1.6569f, -4f, 0f, -4f, -1.6569f, -4f, -4f, -4f, -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 = 256;
int min_size = 32;
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 matrixHeight = size-kernelSize+1;
int matrixWidth = size-kernelSize+1;
int matrixHeight = size;
int matrixWidth = 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
......
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);