Commit c6e15f01 authored by Benedikt Zoennchen's avatar Benedikt Zoennchen
Browse files

merge the OpenCV to LWJGL changes from the private branch into the develop and resolve conflicts

parent fddbac91
package org.vadere.gui.components.utils;
import com.android.dx.gen.Local;
import javax.swing.*;
import org.vadere.gui.projectview.VadereApplication;
......
......@@ -18,6 +18,6 @@ class CLGaussianFilter extends GaussianFilter {
@Override
public void filterImage() {
outputMatrix = this.convolution.convolveSperate(inputMatrix, matrixWidth, matrixHeight, kernel, kernelWidth);
outputMatrix = this.convolution.convolveSeparate(inputMatrix, matrixWidth, matrixHeight, kernel, kernelWidth);
}
}
......@@ -20,9 +20,8 @@ import org.vadere.state.scenario.Topography;
public interface IGaussianFilter {
enum Type {
OpenCV, // old alternative
OpenCL, // default
NativeJava; // not jet implemented
NativeJava // not jet implemented
}
/**
......@@ -87,14 +86,6 @@ public interface IGaussianFilter {
/ (2 * Math.PI * standardDerivation * standardDerivation);
switch (type) {
case OpenCV: {
throw new UnsupportedOperationException();
/*
* return new PedestrianCVGaussianFilter(scenarioBounds, pedestrians, scale,
* scaleFactor, standardDerivation,
* loadingStrategy);
*/
}
case OpenCL: {
try {
BiFunction<Integer, Integer, Float> f =
......@@ -108,7 +99,11 @@ public interface IGaussianFilter {
}
}
default:
throw new IllegalArgumentException(type + " is not jet supported");
BiFunction<Integer, Integer, Float> f =
(centerI, i) -> (float) (Math.sqrt(scaleFactor) * Math.exp(-((centerI - i) / scale)
* ((centerI - i) / scale) / (2 * standardDerivation * standardDerivation)));
IGaussianFilter clFilter = new JGaussianFilter(scenarioBounds, scale, f, false);
return new PedestrianGaussianFilter(pedestrians, clFilter, loadingStrategy);
}
}
......@@ -122,13 +117,6 @@ public interface IGaussianFilter {
final Topography scenario, final double scale,
final boolean scenarioHasBoundary, final double standardDerivation, final Type type) {
switch (type) {
case OpenCV: {
throw new UnsupportedOperationException();
/*
* return new ObstacleCVGaussianFilter(scenario, scale, scenarioHasBoundary,
* standardDerivation);
*/
}
case OpenCL: {
try {
double varianz = standardDerivation * standardDerivation;
......@@ -142,7 +130,11 @@ public interface IGaussianFilter {
}
}
default:
throw new IllegalArgumentException(type + " is not jet supported");
double varianz = standardDerivation * standardDerivation;
BiFunction<Integer, Integer, Float> f = (centerI, i) -> (float) ((1.0 / (2 * Math.PI * varianz))
* Math.exp(-((centerI - i) / scale) * ((centerI - i) / scale) / (2 * varianz)));
IGaussianFilter clFilter = new JGaussianFilter(scenario.getBounds(), scale, f, true);
return new ObstacleGaussianFilter(scenario, clFilter);
}
}
......
......@@ -25,22 +25,6 @@
</resource>
</resources>
<plugins>
<plugin>
<groupId>com.nativelibs4java</groupId>
<artifactId>maven-javacl-plugin</artifactId>
<version>1.0.0-RC4</version>
<configuration>
<sourcesDirectory>${project.build.directory}/../src/org/vadere/util/opencl</sourcesDirectory>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
......@@ -51,75 +35,72 @@
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
com.nativelibs4java
</groupId>
<artifactId>
maven-javacl-plugin
</artifactId>
<versionRange>
[1.0.0-RC4,)
</versionRange>
<goals>
<goal>compile</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>false</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>nativelibs4java-repo</id>
<name>nativelibs4java Maven2 Repository</name>
<url>http://nativelibs4java.sourceforge.net/maven</url>
</repository>
</repositories>
<!-- generated by lwjgl -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<lwjgl.version>3.1.2</lwjgl.version>
</properties>
<!-- end generated by lwjgl -->
<dependencies>
<dependency>
<groupId>com.nativelibs4java</groupId>
<artifactId>bridj</artifactId>
<version>0.7.0</version>
<scope>compile</scope>
<groupId>com.vividsolutions</groupId>
<artifactId>jts</artifactId>
<version>1.13</version>
</dependency>
<!-- generated by lwjgl -->
<dependency>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>com.nativelibs4java</groupId>
<artifactId>javacl</artifactId>
<version>1.0.0-RC4</version>
<scope>compile</scope>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl-opencl</artifactId>
<version>${lwjgl.version}</version>
</dependency>
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts</artifactId>
<version>1.13</version>
<groupId>org.lwjgl</groupId>
<artifactId>lwjgl</artifactId>
<version>${lwjgl.version}</version>
<classifier>${lwjgl.natives}</classifier>
<scope>runtime</scope>
</dependency>
</dependencies>
<!-- end generated by lwjgl -->
<profiles>
<profile>
<id>lwjgl-natives-linux</id>
<activation>
<os><family>unix</family></os>
</activation>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lwjgl.natives>natives-linux</lwjgl.natives>
</properties>
</profile>
<profile>
<id>lwjgl-natives-macos</id>
<activation>
<os><family>mac</family></os>
</activation>
<properties>
<lwjgl.natives>natives-macos</lwjgl.natives>
</properties>
</profile>
<profile>
<id>lwjgl-natives-windows</id>
<activation>
<os><family>windows</family></os>
</activation>
<properties>
<lwjgl.natives>natives-windows</lwjgl.natives>
</properties>
</profile>
</profiles>
<!--<packaging>pom</packaging> -->
</project>
\ No newline at end of file
package org.vadere.util.math;
import com.nativelibs4java.opencl.*;
import org.bridj.Pointer;
import org.vadere.util.opencl.kernels.Convolve;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.lwjgl.BufferUtils;
import org.lwjgl.PointerBuffer;
import org.lwjgl.opencl.CLContextCallback;
import org.lwjgl.opencl.CLProgramCallback;
import org.lwjgl.system.MemoryStack;
import org.vadere.util.opencl.IOUtil;
import org.vadere.util.opencl.InfoUtils;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import static org.lwjgl.opencl.CL10.*;
import static org.lwjgl.system.MemoryUtil.NULL;
import static org.lwjgl.system.MemoryUtil.memUTF8;
/**
* @author Benedikt Zoennchen
*/
public class CLConvolution {
private static Logger log = LogManager.getLogger(CLConvolution.class);
private CLContext context;
private Convolve gaussianFilter;
private Convolution gaussianFilter;
public CLConvolution() throws IOException {
//context = JavaCL.createBestContext(CLPlatform.DeviceFeature.CPU, CLPlatform.DeviceFeature.MaxComputeUnits);
context = JavaCL.createBestContext();
gaussianFilter = new Convolve(context);
}
// CL ids
private MemoryStack stack;
private long clPlatform;
private long clDevice;
private long clContext;
private long clQueue;
private long clProgram;
public CLConvolution(CLPlatform.DeviceFeature... deviceFeature) throws IOException {
context = JavaCL.createBestContext(deviceFeature);
gaussianFilter = new Convolve(context);
}
// error code buffer
private IntBuffer errcode_ret;
public float[] convolve(final float[] input, final int matrixWidth, final int matrixHeight, final float[] kernel,
final int kernelWidth) throws IOException {
float[] output = new float[input.length];
CLQueue queue = context.createDefaultQueue();
// CL Memory
private long clInput;
private long clOutput;
private long clGaussianKernel;
private long clTmp;
CLBuffer<Float> clInput = doubleArrayToCLBuffer(input);
CLBuffer<Float> clKernel = doubleArrayToCLBuffer(kernel);
CLBuffer<Float> clOutput = doubleArrayToCLBuffer(output);
// Host Memory
private FloatBuffer hostScenario;
private FloatBuffer hostGaussKernel;
private FloatBuffer output;
// timer.start();
CLEvent convolveEvt = gaussianFilter.convolve(queue, clInput, clKernel, clOutput, matrixWidth, matrixHeight,
kernelWidth, new int[] {matrixWidth, input.length / matrixWidth}, null);
// CL callbacks
private CLContextCallback contextCB;
private CLProgramCallback programCB;
queue.finish();
convolveEvt.waitFor();
Pointer<Float> outPtr = clOutput.read(queue, convolveEvt);
// CL kernel
private long clKernelConvolve;
private long clKernelConvolveRow;
private long clKernelConvolveCol;
for (int i = 0; i < output.length; i++) {
output[i] = outPtr.get(i);
public CLConvolution() {
this.stack = MemoryStack.stackPush();
}
outPtr.release();
return output;
public void init() {
initCallbacks();
initCL();
buildProgram();
}
public float[] convolveSperate(final float[] input, final int matrixWidth, final int matrixHeight,
final float[] kernel, final int kernelWidth) {
float[] output = new float[input.length];
float[] tmp = new float[input.length];
CLQueue queue = context.createDefaultQueue();
CLBuffer<Float> clInput = doubleArrayToCLBuffer(input);
CLBuffer<Float> clKernel = doubleArrayToCLBuffer(kernel);
CLBuffer<Float> clOutput = doubleArrayToCLBuffer(output);
CLBuffer<Float> clTmp = doubleArrayToCLBuffer(tmp);
CLEvent convolveEvtCol = gaussianFilter.convolveCol(queue, clInput, clKernel, clTmp, matrixWidth, matrixHeight,
kernelWidth, new int[] {matrixWidth, input.length / matrixWidth}, null);
convolveEvtCol.waitFor();
CLEvent convolveEvtRow = gaussianFilter.convolveRow(queue, clTmp, clKernel, clOutput, matrixWidth, matrixHeight,
kernelWidth, new int[] {matrixWidth, input.length / matrixWidth}, null);
queue.finish();
convolveEvtRow.waitFor();
Pointer<Float> outPtr = clOutput.read(queue, convolveEvtRow);
for (int i = 0; i < output.length; i++) {
output[i] = outPtr.get(i);
public float[] convolve(final float[] input,
final int matrixWidth,
final int matrixHeight,
final float[] kernel,
final int kernelWidth) {
init();
float[] result = convolve(input, matrixWidth, matrixHeight, kernel, kernelWidth, clKernelConvolve);
clearCL();
clReleaseKernel(clKernelConvolve);
return result;
}
outPtr.release();
return output;
public float[] convolveRow(final float[] input, final int matrixWidth, final int matrixHeight, final float[] kernel,
final int kernelWidth) {
init();
float[] result = convolve(input, matrixWidth, matrixHeight, kernel, kernelWidth, clKernelConvolveRow);
clearCL();
clReleaseKernel(clKernelConvolveRow);
return result;
}
public float[] convolveCol(final float[] input, final int matrixWidth, final int matrixHeight, final float[] kernel,
final int kernelWidth) {
float[] output = new float[input.length];
CLQueue queue = context.createDefaultQueue();
init();
float[] result = convolve(input, matrixWidth, matrixHeight, kernel, kernelWidth, clKernelConvolveCol);
clearCL();
clReleaseKernel(clKernelConvolveCol);
return result;
}
public float[] convolveSeparate(final float[] input, final int matrixWidth, final int matrixHeight, final float[] kernel,
final int kernelWidth) {
assert matrixWidth * matrixHeight == input.length;
init();
hostScenario = CLUtils.toFloatBuffer(input);
output = CLUtils.toFloatBuffer(input);
hostGaussKernel = CLUtils.toFloatBuffer(kernel);
CLBuffer<Float> clInput = doubleArrayToCLBuffer(input);
CLBuffer<Float> clKernel = doubleArrayToCLBuffer(kernel);
CLBuffer<Float> clOutput = doubleArrayToCLBuffer(output);
// host memory to gpu memory
clInput = clCreateBuffer(clContext, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, hostScenario, errcode_ret);
clTmp = clCreateBuffer(clContext, CL_MEM_READ_WRITE, 4 * input.length, errcode_ret);
clOutput = clCreateBuffer(clContext, CL_MEM_WRITE_ONLY, 4 * input.length, errcode_ret);
clGaussianKernel = clCreateBuffer(clContext, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, hostGaussKernel, errcode_ret);
CLEvent convolveEvtCol = gaussianFilter.convolveCol(queue, clInput, clKernel, clOutput, matrixWidth,
matrixHeight, kernelWidth, new int[] {matrixWidth, input.length / matrixWidth}, null);
convolveEvtCol.waitFor();
queue.finish();
clSetKernelArg1p(clKernelConvolveCol, 0, clInput);
clSetKernelArg1p(clKernelConvolveCol, 1, clGaussianKernel);
clSetKernelArg1p(clKernelConvolveCol, 2, clTmp);
clSetKernelArg1i(clKernelConvolveCol, 3, matrixWidth);
clSetKernelArg1i(clKernelConvolveCol, 4, matrixHeight);
clSetKernelArg1i(clKernelConvolveCol, 5, kernelWidth);
Pointer<Float> outPtr = clOutput.read(queue, convolveEvtCol);
for (int i = 0; i < output.length; i++) {
output[i] = outPtr.get(i);
clSetKernelArg1p(clKernelConvolveRow, 0, clTmp);
clSetKernelArg1p(clKernelConvolveRow, 1, clGaussianKernel);
clSetKernelArg1p(clKernelConvolveRow, 2, clOutput);
clSetKernelArg1i(clKernelConvolveRow, 3, matrixWidth);
clSetKernelArg1i(clKernelConvolveRow, 4, matrixHeight);
clSetKernelArg1i(clKernelConvolveRow, 5, kernelWidth);
PointerBuffer clGlobalWorkSizeEdges = BufferUtils.createPointerBuffer(2);
clGlobalWorkSizeEdges.put(0, matrixWidth);
clGlobalWorkSizeEdges.put(1, matrixHeight);
// run the kernel and read the result
clEnqueueNDRangeKernel(clQueue, clKernelConvolveCol, 2, null, clGlobalWorkSizeEdges, null, null, null);
clEnqueueNDRangeKernel(clQueue, clKernelConvolveRow, 2, null, clGlobalWorkSizeEdges, null, null, null);
clFinish(clQueue);
clEnqueueReadBuffer(clQueue, clOutput, true, 0, output, null, null);
float[] foutput = CLUtils.toFloatArray(output, input.length);
clearCL();
clReleaseKernel(clTmp);
clReleaseKernel(clKernelConvolve);
clReleaseKernel(clKernelConvolveRow);
clReleaseKernel(clKernelConvolveCol);
return foutput;
}
outPtr.release();
return output;
private float[] convolve(final float[] input,
final int matrixWidth,
final int matrixHeight,
final float[] kernel,
final int kernelWidth, final long clKernel) {
assert matrixWidth * matrixHeight == input.length;
setArguments(input, matrixWidth, matrixHeight, kernel, kernelWidth, clKernel);
PointerBuffer clGlobalWorkSizeEdges = BufferUtils.createPointerBuffer(2);
clGlobalWorkSizeEdges.put(0, matrixWidth);
clGlobalWorkSizeEdges.put(1, matrixHeight);
// run the kernel and read the result
clEnqueueNDRangeKernel(clQueue, clKernel, 2, null, clGlobalWorkSizeEdges, null, null, null);
clFinish(clQueue);
clEnqueueReadBuffer(clQueue, clOutput, true, 0, output, null, null);
float[] foutput = CLUtils.toFloatArray(output, input.length);
return foutput;
}
public float[] convolveRow(final float[] input, final int matrixWidth, final int matrixHeight, final float[] kernel,
final int kernelWidth) {
float[] output = new float[input.length];
float[] tmp = new float[input.length];
CLQueue queue = context.createDefaultQueue();
CLBuffer<Float> clInput = doubleArrayToCLBuffer(input);
CLBuffer<Float> clKernel = doubleArrayToCLBuffer(kernel);
CLBuffer<Float> clOutput = doubleArrayToCLBuffer(output);
CLEvent convolveEvtRow = gaussianFilter.convolveRow(queue, clInput, clKernel, clOutput, matrixWidth,
matrixHeight, kernelWidth, new int[] {matrixWidth, input.length / matrixWidth}, null);
queue.finish();
convolveEvtRow.waitFor();
Pointer<Float> outPtr = clOutput.read(queue, convolveEvtRow);
for (int i = 0; i < output.length; i++) {
output[i] = outPtr.get(i);
private void setArguments(final float[] input, final int matrixWidth, final int matrixHeight, final float[] kernel, final int kernelWidth, final long clKernel) {
hostScenario = CLUtils.toFloatBuffer(input);
output = CLUtils.toFloatBuffer(input);
hostGaussKernel = CLUtils.toFloatBuffer(kernel);
// host memory to gpu memory
clInput = clCreateBuffer(clContext, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, hostScenario, errcode_ret);
clOutput = clCreateBuffer(clContext, CL_MEM_WRITE_ONLY, 4 * input.length, errcode_ret);
clGaussianKernel = clCreateBuffer(clContext, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, hostGaussKernel, errcode_ret);
clSetKernelArg1p(clKernel, 0, clInput);
clSetKernelArg1p(clKernel, 1, clGaussianKernel);
clSetKernelArg1p(clKernel, 2, clOutput);
clSetKernelArg1i(clKernel, 3, matrixWidth);
clSetKernelArg1i(clKernel, 4, matrixHeight);
clSetKernelArg1i(clKernel, 5, kernelWidth);
}
private void clearCL() {
// release memory and devices
contextCB.free();
programCB.free();
clReleaseMemObject(clInput);
clReleaseMemObject(clOutput);
clReleaseCommandQueue(clQueue);
clReleaseProgram(clProgram);
clReleaseContext(clContext);
}
// private helpers
private void initCallbacks() {
contextCB = CLContextCallback.create((errinfo, private_info, cb, user_data) ->
{
log.warn("[LWJGL] cl_context_callback");
log.warn("\tInfo: " + memUTF8(errinfo));
});
programCB = CLProgramCallback.create((program, user_data) ->
{
log.info("The cl_program [0x"+program+"] was built " + (InfoUtils.getProgramBuildInfoInt(program, clDevice, CL_PROGRAM_BUILD_STATUS) == CL_SUCCESS ? "successfully" : "unsuccessfully"));
});
}
private void initCL() {
// helper for the memory allocation in java
//stack = MemoryStack.stackPush();
errcode_ret = stack.callocInt(1);
IntBuffer numberOfPlatforms = stack.mallocInt(1);
clGetPlatformIDs(null, numberOfPlatforms);
PointerBuffer platformIDs = stack.mallocPointer(numberOfPlatforms.get(0));
clGetPlatformIDs(platformIDs, numberOfPlatforms);
clPlatform = platformIDs.get(0);
IntBuffer numberOfDevices = stack.mallocInt(1);
clGetDeviceIDs(clPlatform, CL_DEVICE_TYPE_GPU, null, numberOfDevices);
PointerBuffer deviceIDs = stack.mallocPointer(numberOfDevices.get(0));
clGetDeviceIDs(clPlatform, CL_DEVICE_TYPE_GPU, deviceIDs, numberOfDevices);
clDevice = deviceIDs.get(0);
printDeviceInfo(clDevice, "CL_DEVICE_NAME", CL_DEVICE_NAME);
PointerBuffer ctxProps = stack.mallocPointer(3);
ctxProps.put(CL_CONTEXT_PLATFORM)
.put(clPlatform)
.put(NULL)
.flip();
clContext = clCreateContext(ctxProps, clDevice, contextCB, NULL, errcode_ret);
InfoUtils.checkCLError(errcode_ret);
clQueue = clCreateCommandQueue(clContext, clDevice, 0, errcode_ret);
}
outPtr.release();
return output;
private void buildProgram() {
PointerBuffer strings = BufferUtils.createPointerBuffer(1);
PointerBuffer lengths = BufferUtils.createPointerBuffer(1);
ByteBuffer source;
try {
source = IOUtil.ioResourceToByteBuffer("Convolve.cl", 4096);
} catch (IOException e) {