aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/jogamp/opencl/CLProgramBuilder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/jogamp/opencl/CLProgramBuilder.java')
-rw-r--r--src/com/jogamp/opencl/CLProgramBuilder.java77
1 files changed, 60 insertions, 17 deletions
diff --git a/src/com/jogamp/opencl/CLProgramBuilder.java b/src/com/jogamp/opencl/CLProgramBuilder.java
index ece9ba36..389adce8 100644
--- a/src/com/jogamp/opencl/CLProgramBuilder.java
+++ b/src/com/jogamp/opencl/CLProgramBuilder.java
@@ -48,6 +48,7 @@ import java.util.Set;
/**
* CLProgramBuilder is a helper for building programs with more complex configurations or
* building multiple programs with similar configurations.
+ * CLProgramBuilder is used to create {@link CLProgramConfiguration}s and {@link CLBuildConfiguration}s.
* @see CLProgram#prepare()
* @see #createConfiguration()
* @see #createConfiguration(com.jogamp.opencl.CLProgram)
@@ -113,13 +114,13 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa
* The CLProgram is initialized and ready to be build after this method call.
* This method prefers program initialization from binaries if this fails or if
* no binaries have been found, it will try to load the program from sources. If
- * This also fails an appropriate exception will be thrown.
+ * this also fails an appropriate exception will be thrown.
* @param ois The ObjectInputStream for reading the object.
* @param context The context used for program initialization.
*/
public static CLProgramConfiguration loadConfiguration(ObjectInputStream ois, CLContext context) throws IOException, ClassNotFoundException {
CLProgramBuilder config = (CLProgramBuilder) ois.readObject();
- if(config.binariesMap.size() > 0 && config.binariesMap.values().iterator().next().length > 0) {
+ if(allBinariesAvailable(config)) {
try{
config.program = context.createProgram(config.binariesMap);
}catch(CLException.CLInvalidBinaryException ex) {
@@ -136,6 +137,15 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa
}
return config;
}
+
+ private static boolean allBinariesAvailable(CLProgramBuilder config) {
+ for (Map.Entry<CLDevice, byte[]> entry : config.binariesMap.entrySet()) {
+ if(Arrays.equals(NO_BINARIES, entry.getValue())) {
+ return false;
+ }
+ }
+ return config.binariesMap.size() > 0;
+ }
@Override
public void save(ObjectOutputStream oos) throws IOException {
@@ -195,14 +205,16 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa
@Override
public CLProgramBuilder forDevice(CLDevice device) {
- binariesMap.put(device, NO_BINARIES);
+ if(!binariesMap.containsKey(device)) {
+ binariesMap.put(device, NO_BINARIES);
+ }
return this;
}
@Override
public CLProgramBuilder forDevices(CLDevice... devices) {
for (CLDevice device : devices) {
- binariesMap.put(device, NO_BINARIES);
+ forDevice(device);
}
return this;
}
@@ -260,20 +272,43 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa
optionSet.clear();
return this;
}
+
+ private int indexOf(CLDevice device, CLDevice[] devices) {
+ for (int i = 0; i < devices.length; i++) {
+ if(device.equals(devices[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
// format: { platform_suffix, num_binaries, (device.ID, length, binaries)+ }
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
- Set<CLDevice> devices = binariesMap.keySet();
- String suffix = devices.iterator().next().getPlatform().getICDSuffix();
- out.writeUTF(suffix);
-
- out.writeInt(binariesMap.size());
+ CLDevice[] deviceList = null;
+ String suffix = null;
+
+ if(!binariesMap.isEmpty()) {
+ CLPlatform platform = binariesMap.keySet().iterator().next().getPlatform();
+ deviceList = platform.listCLDevices();
- for (CLDevice device : devices) {
- byte[] binaries = binariesMap.get(device);
- out.writeLong(device.ID);
+ suffix = platform.getICDSuffix();
+ }
+
+ out.writeUTF(suffix); // null if we have no binaries or no devices specified
+ out.writeInt(binariesMap.size()); // may be 0
+
+ for (Map.Entry<CLDevice, byte[]> entry : binariesMap.entrySet()) {
+ CLDevice device = entry.getKey();
+ byte[] binaries = entry.getValue();
+
+ // we use the device index as identifier since there is currently no other way
+ // to distinguish identical devices via CL.
+ // it should be persistent between runs but may change on driver/hardware update. In this situations we would
+ // have to build from source anyway (build failures).
+ int index = indexOf(device, deviceList);
+ out.writeInt(index);
out.writeInt(binaries.length);
out.write(binaries);
}
@@ -290,18 +325,26 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa
break;
}
}
-
+
this.binariesMap = new LinkedHashMap<CLDevice, byte[]>();
+
+ CLDevice[] devices = null;
+ if(platform != null) {
+ devices = platform.listCLDevices();
+ }
+
int mapSize = in.readInt();
for (int i = 0; i < mapSize; i++) {
- long deviceID = in.readLong();
+ int index = in.readInt();
int length = in.readInt();
byte[] binaries = new byte[length];
in.readFully(binaries);
-
- CLDevice device = new CLDevice(CLPlatform.getLowLevelCLInterface(), platform, deviceID);
- binariesMap.put(device, binaries);
+
+ // we ignore binaries we can't map to devices
+ if(devices != null && index >= 0 && index < devices.length) {
+ binariesMap.put(devices[index], binaries);
+ }
}
}