summaryrefslogtreecommitdiffstats
path: root/src/com/mbien/opencl/CLProgram.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/mbien/opencl/CLProgram.java')
-rw-r--r--src/com/mbien/opencl/CLProgram.java158
1 files changed, 87 insertions, 71 deletions
diff --git a/src/com/mbien/opencl/CLProgram.java b/src/com/mbien/opencl/CLProgram.java
index 6f1ed551..dfe084c7 100644
--- a/src/com/mbien/opencl/CLProgram.java
+++ b/src/com/mbien/opencl/CLProgram.java
@@ -8,11 +8,12 @@ import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
import java.util.Map;
import static com.mbien.opencl.CLException.*;
import static com.mbien.opencl.CL.*;
-import java.util.Set;
/**
* Represents a OpenCL program executed on one or more {@link CLDevice}s.
@@ -25,7 +26,7 @@ public class CLProgram implements CLResource {
private final CL cl;
- private Map<String, CLKernel> kernels;
+ private final Set<CLKernel> kernels;
private Map<CLDevice, Status> buildStatusMap;
private boolean executable;
@@ -35,6 +36,7 @@ public class CLProgram implements CLResource {
this.cl = context.cl;
this.context = context;
+ this.kernels = new HashSet<CLKernel>();
IntBuffer ib = BufferFactory.newDirectByteBuffer(4).asIntBuffer();
// Create the program
@@ -47,6 +49,7 @@ public class CLProgram implements CLResource {
this.cl = context.cl;
this.context = context;
+ this.kernels = new HashSet<CLKernel>();
PointerBuffer devices = PointerBuffer.allocateDirect(binaries.size());
PointerBuffer lengths = PointerBuffer.allocateDirect(binaries.size());
@@ -80,38 +83,6 @@ public class CLProgram implements CLResource {
}
- private final void initKernels() {
-
- if(kernels == null) {
-
- IntBuffer numKernels = BufferFactory.newDirectByteBuffer(4).asIntBuffer();
- int ret = cl.clCreateKernelsInProgram(ID, 0, null, numKernels);
- checkForError(ret, "can not create kernels for program");
-
- if(numKernels.get(0) > 0) {
- HashMap<String, CLKernel> map = new HashMap<String, CLKernel>();
-
- PointerBuffer kernelIDs = PointerBuffer.allocateDirect(numKernels.get(0));
- ret = cl.clCreateKernelsInProgram(ID, kernelIDs.capacity(), kernelIDs, null);
- checkForError(ret, "can not create kernels for program");
-
- for (int i = 0; i < kernelIDs.capacity(); i++) {
- CLKernel kernel = new CLKernel(this, kernelIDs.get(i));
- map.put(kernel.name, kernel);
- }
- this.kernels = map;
- }else{
- initBuildStatus();
- if(!isExecutable()) {
- // It is illegal to create kernels from a not executable program.
- // For consistency between AMD and NVIDIA drivers throw an exception at this point.
- throw new CLException(CL_INVALID_PROGRAM_EXECUTABLE,
- "can not initialize kernels, program is not executable. status: "+buildStatusMap);
- }
- }
- }
- }
-
private final void initBuildStatus() {
if(buildStatusMap == null) {
@@ -235,7 +206,7 @@ public class CLProgram implements CLResource {
*/
public CLProgram build(String options, CLDevice... devices) {
- if(kernels != null) {
+ if(!kernels.isEmpty()) {
//No changes to the program executable are allowed while there are
//kernel objects associated with a program object.
releaseKernels();
@@ -266,8 +237,83 @@ public class CLProgram implements CLResource {
return this;
}
+ /**
+ * Creates a kernel with the specified kernel name.
+ */
+ public CLKernel createCLKernel(String kernelName) {
+
+ if(released) {
+ return null;
+ }
+
+ int[] err = new int[1];
+ long id = cl.clCreateKernel(ID, kernelName, err, 0);
+ checkForError(err[0], "unable to create Kernel with name: "+kernelName);
+
+ CLKernel kernel = new CLKernel(this, id);
+ kernels.add(kernel);
+ return kernel;
+ }
+
+ /**
+ * Creates n instances of a kernel with the specified kernel name.
+ */
+ /*
+ public CLKernel[] createCLKernels(String kernelName, int instanceCount) {
+
+ if(released) {
+ return new CLKernel[0];
+ }
+
+ CLKernel[] newKernels = new CLKernel[instanceCount];
+ for (int i = 0; i < newKernels.length; i++) {
+ newKernels[i] = createCLKernel(kernelName);
+ }
+ return newKernels;
+ }
+ */
+
+ /**
+ * Creates all kernels of this program and stores them a Map with the kernel name as key.
+ */
+ public Map<String, CLKernel> createCLKernels() {
+
+ if(released) {
+ return Collections.emptyMap();
+ }
+
+ HashMap<String, CLKernel> newKernels = new HashMap<String, CLKernel>();
+
+ IntBuffer numKernels = BufferFactory.newDirectByteBuffer(4).asIntBuffer();
+ int ret = cl.clCreateKernelsInProgram(ID, 0, null, numKernels);
+ checkForError(ret, "can not create kernels for program");
+
+ if(numKernels.get(0) > 0) {
+
+ PointerBuffer kernelIDs = PointerBuffer.allocateDirect(numKernels.get(0));
+ ret = cl.clCreateKernelsInProgram(ID, kernelIDs.capacity(), kernelIDs, null);
+ checkForError(ret, "can not create kernels for program");
+
+ for (int i = 0; i < kernelIDs.capacity(); i++) {
+ CLKernel kernel = new CLKernel(this, kernelIDs.get(i));
+ kernels.add(kernel);
+ newKernels.put(kernel.name, kernel);
+ }
+ }else{
+ initBuildStatus();
+ if(!isExecutable()) {
+ // It is illegal to create kernels from a not executable program.
+ // For consistency between AMD and NVIDIA drivers throw an exception at this point.
+ throw new CLException(CL_INVALID_PROGRAM_EXECUTABLE,
+ "can not initialize kernels, program is not executable. status: "+buildStatusMap);
+ }
+ }
+
+ return newKernels;
+ }
+
void onKernelReleased(CLKernel kernel) {
- this.kernels.remove(kernel.name);
+ this.kernels.remove(kernel);
}
/**
@@ -287,43 +333,13 @@ public class CLProgram implements CLResource {
}
private void releaseKernels() {
- if(kernels != null) {
- String[] names = kernels.keySet().toArray(new String[kernels.size()]);
- for (String name : names) {
- kernels.get(name).release();
+ if(!kernels.isEmpty()) {
+ // copy to array to prevent concurrent modification exception
+ CLKernel[] array = kernels.toArray(new CLKernel[kernels.size()]);
+ for (CLKernel kernel : array) {
+ kernel.release();
}
- kernels = null;
- }
- }
-
- /**
- * Returns the kernel with the specified name.
- * @throws IllegalArgumentException when no kernel with the specified name exists in this program.
- */
- public CLKernel getCLKernel(String kernelName) {
- if(released) {
- return null;
- }
- initKernels();
- final CLKernel kernel = kernels.get(kernelName);
- if(kernel == null) {
- throw new IllegalArgumentException(
- this+" does not contain a kernel with the name '"+kernelName+"'");
- }
- return kernel;
- }
-
-
- /**
- * Returns all kernels of this program in a unmodifiable view of a map
- * with the kernel function names as keys.
- */
- public Map<String, CLKernel> getCLKernels() {
- if(released) {
- return Collections.emptyMap();
}
- initKernels();
- return Collections.unmodifiableMap(kernels);
}
/**