Jogamp
Fix unit test bugs on Mac OS X 64-bit.
authorWade Walker <wwalker3@austin.rr.com>
Sat, 8 Feb 2014 20:00:41 +0000 (14:00 -0600)
committerWade Walker <wwalker3@austin.rr.com>
Sat, 8 Feb 2014 20:00:41 +0000 (14:00 -0600)
This commit fixes bugs 959 (local work size set incorrectly),
960 (concurrencyTest() throws ConcurrentModificationException)
963 (programBinariesTest() causes SIGSEGV) and 964 (builderTest()
cases CL_INVALID_VALUE). After this commit, all JOCL tests should
pass on 64-bit Mac OS X.

src/com/jogamp/opencl/CLContext.java
src/com/jogamp/opencl/CLDevice.java
src/com/jogamp/opencl/CLProgram.java
src/com/jogamp/opencl/CLProgramBuilder.java
test/com/jogamp/opencl/CLCommandQueueTest.java

index c3bd0e3..163375e 100644 (file)
@@ -287,6 +287,7 @@ public class CLContext extends CLObjectResource {
      */
     public CLProgram createProgram(Map<CLDevice, byte[]> binaries) {
         CLProgram program = CLProgram.create(this, binaries);
+        program.setNoSource();
         programs.add(program);
         return program;
     }
@@ -486,11 +487,8 @@ public class CLContext extends CLObjectResource {
     
     private void release(Collection<? extends CLResource> resources) {
         // resources remove themselves when released, see above
-        if(!resources.isEmpty()) {
-            CLResource[] array = resources.toArray(new CLResource[resources.size()]);
-            for (CLResource resource : array) {
-                resource.release();
-            }
+        while(!resources.isEmpty()) {
+            resources.iterator().next().release();
         }
     }
 
@@ -509,9 +507,8 @@ public class CLContext extends CLObjectResource {
 
             synchronized(queuesMap) {
                 final Collection<List<CLCommandQueue>> queuesList =  queuesMap.values();
-                for( Iterator<List<CLCommandQueue>> queuesI = queuesList.iterator(); queuesI.hasNext(); ) {
-                    release(queuesI.next());
-                }
+                while(!queuesList.isEmpty())
+                    release(queuesList.iterator().next());
             }
 
         } finally {
index b47deb2..25fb009 100644 (file)
@@ -635,6 +635,15 @@ public class CLDevice extends CLObject {
     }
 
     /**
+     * Returns {@link #isExtensionAvailable}("cl_khr_icd").
+     * @see #getExtensions()
+     */
+    @CLProperty("cl_khr_icd")
+    public boolean isICDAvailable() {
+        return isExtensionAvailable("cl_khr_icd");
+    }
+
+    /**
      * Returns {@link #isExtensionAvailable}("cl_khr_gl_sharing") || {@link #isExtensionAvailable}("cl_APPLE_gl_sharing").
      * @see #getExtensions()
      */
@@ -850,7 +859,7 @@ public class CLDevice extends CLObject {
         ROUND_TO_NEAREST(CL_FP_ROUND_TO_NEAREST),
 
         /**
-         * round to +ve and –ve infinity rounding modes supported.
+         * round to positive and negative infinity rounding modes supported.
          */
         ROUND_TO_INF(CL_FP_ROUND_TO_INF),
 
index 3919d37..9dd3db8 100644 (file)
@@ -70,6 +70,8 @@ public class CLProgram extends CLObjectResource {
 
     private boolean executable;
     private boolean released;
+    /** Set if program created from binary, or else getting source can crash the driver on Macs. */
+    private boolean noSource;
 
     private CLProgram(CLContext context, long id) {
         super(context, id);
@@ -592,10 +594,20 @@ public class CLProgram extends CLObjectResource {
     }
 
     /**
+     * Must set this if the program is created from binary so we know not to call getSource(),
+     * which can SIGSEGV on Macs if there is no source.
+     */
+    public void setNoSource() {
+        noSource = true;
+    }
+
+    /**
      * Returns the source code of this program. Note: sources are not cached,
      * each call of this method calls into Open
      */
     public String getSource() {
+        if(noSource)
+            return "";
         // some drivers return IVE codes if the program haven't been built from source.
         try{
             return getProgramInfoString(CL_PROGRAM_SOURCE);
@@ -810,7 +822,7 @@ public class CLProgram extends CLObjectResource {
         public final static String UNSAFE_MATH = "-cl-unsafe-math-optimizations";
 
         /**
-         * Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or ±∞.
+         * Allow optimizations for floating-point arithmetic that assume that arguments and results are not NaNs or plus/minus infinity.
          * This option may violate the OpenCL numerical compliance requirements defined in in section 7.4 for
          * single-precision floating-point, section 9.3.9 for double-precision floating-point, and edge case behavior in section 7.5.
          */
index e80b992..dd0c64f 100644 (file)
@@ -276,14 +276,16 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa
     private void writeObject(ObjectOutputStream out) throws IOException {
         out.defaultWriteObject();
 
-        String suffix = null;
+        String suffix = "";
 
         if(!binariesMap.isEmpty()) {
-            CLPlatform platform = binariesMap.keySet().iterator().next().getPlatform();
-            suffix = platform.getICDSuffix();
+            CLDevice device = binariesMap.keySet().iterator().next();
+            if(device.isICDAvailable())
+                suffix = device.getPlatform().getICDSuffix();
         }
         
-        out.writeUTF(suffix);               // null if we have no binaries or no devices specified
+        // empty string if we have no binaries or no devices specified, or if cl_khr_icd isn't supported
+        out.writeUTF(suffix);
         out.writeInt(binariesMap.size());   // may be 0
 
         for (Map.Entry<CLDevice, byte[]> entry : binariesMap.entrySet()) {
@@ -299,22 +301,22 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa
     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
         in.defaultReadObject();
 
-        String suffix = in.readUTF();
+        String suffix = in.readUTF();  // empty string means no suffix was written; just picks first platform
         CLPlatform platform = null;
         for (CLPlatform p : CLPlatform.listCLPlatforms()) {
-            if(p.getICDSuffix().equals(suffix)) {
+            if(suffix.isEmpty() || p.getICDSuffix().equals(suffix)) {
                 platform = p;
                 break;
             }
         }
-        
+
         this.binariesMap = new LinkedHashMap<CLDevice, byte[]>();
         
         List<CLDevice> devices;
         if(platform != null) {
-            devices = new ArrayList(Arrays.asList(platform.listCLDevices()));
+            devices = new ArrayList<CLDevice>(Arrays.asList(platform.listCLDevices()));
         }else{
-            devices = Collections.EMPTY_LIST;
+            devices = Collections.emptyList();
         }
         
         int mapSize = in.readInt();
index c9b1b56..672cc8b 100644 (file)
@@ -474,7 +474,9 @@ public class CLCommandQueueTest extends UITestCase {
                 @Override
                 public void run() {
 
-                    int groupSize = queue2.getDevice().getMaxWorkItemSizes()[0];
+                    int maxWorkItemSize = queue2.getDevice().getMaxWorkItemSizes()[0];
+                    int kernelWorkGroupSize = (int)vectorAddKernel2.getWorkGroupSize( queue2.getDevice() );
+                    int localWorkSize = Math.min( maxWorkItemSize, kernelWorkGroupSize );
 
                     fillBuffer(clBufferA2.buffer, 12345);
                     fillBuffer(clBufferB2.buffer, 67890);
@@ -488,7 +490,7 @@ public class CLCommandQueueTest extends UITestCase {
 
     //                System.out.println("D kernels");
                     CLEventList events2 = new CLEventList(2);
-                    queue2.put1DRangeKernel(vectorAddKernel2, 0, elements, groupSize, events2);
+                    queue2.put1DRangeKernel(vectorAddKernel2, 0, elements, localWorkSize, events2);
                     queue2.putReadBuffer(clBufferD, false, events2);
 
                     barrier.waitFor(queue2, events2);
http://JogAmp.org git info: FAQ, tutorial and man pages.