aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Bien <[email protected]>2011-04-19 04:12:54 +0200
committerMichael Bien <[email protected]>2011-04-19 04:12:54 +0200
commit03ce3ff819e342b95552c1438ea1269fd30e7176 (patch)
tree426d9782e7340862615131a971df5fe2dd7311ac
parenta3654a0b8a4e0c9e246aa04019bf1d5a09e7a28d (diff)
CLBuildConfiguration.save(..) should store device index and not the device id.
updated javadoc.
-rw-r--r--src/com/jogamp/opencl/CLProgramBuilder.java55
-rw-r--r--src/com/jogamp/opencl/util/CLBuildConfiguration.java8
2 files changed, 53 insertions, 10 deletions
diff --git a/src/com/jogamp/opencl/CLProgramBuilder.java b/src/com/jogamp/opencl/CLProgramBuilder.java
index ece9ba36..bcde3db6 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,6 +272,15 @@ 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 {
@@ -273,7 +294,13 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa
for (CLDevice device : devices) {
byte[] binaries = binariesMap.get(device);
- out.writeLong(device.ID);
+
+ // 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, device.getPlatform().listCLDevices());
+ out.writeInt(index);
out.writeInt(binaries.length);
out.write(binaries);
}
@@ -290,18 +317,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);
+ }
}
}
diff --git a/src/com/jogamp/opencl/util/CLBuildConfiguration.java b/src/com/jogamp/opencl/util/CLBuildConfiguration.java
index f70f088e..89f59110 100644
--- a/src/com/jogamp/opencl/util/CLBuildConfiguration.java
+++ b/src/com/jogamp/opencl/util/CLBuildConfiguration.java
@@ -36,6 +36,14 @@ import java.util.Map;
/**
* Configuration representing everything needed to build an OpenCL program.
+ * <p>
+ * If you use {@link #save(java.io.ObjectOutputStream)} to persist build configurations between
+ * JVM sessions it is highly recommended to call {@link #forDevice(com.jogamp.opencl.CLDevice) }
+ * or {@link #forDevices(com.jogamp.opencl.CLDevice[]) } before building the program.
+ * Driver updates or HW changes can make exact device-to-binary mapping hard, the
+ * builder will drop all unmappable binaries silently. Setting the devices explicitly will
+ * force automatic rebuilds from source in this situation.
+ * </p>
* @author Michael Bien
* @see com.jogamp.opencl.CLProgramBuilder#createConfiguration()
* @see com.jogamp.opencl.CLProgramBuilder#loadConfiguration(java.io.ObjectInputStream)