Jogamp
Fix crashes due to AMD driver bugs.
authorWade Walker <wwalker3@austin.rr.com>
Sat, 8 Mar 2014 22:17:36 +0000 (16:17 -0600)
committerWade Walker <wwalker3@austin.rr.com>
Sat, 8 Mar 2014 22:17:36 +0000 (16:17 -0600)
programBinariesTest() failure was due to AMD drivers crashing
in clCreateKernelsInProgram() when the program is not built yet,
instead of returning error code CL_INVALID_PROGRAM_EXECUTABLE as they
should.

lowLevelVectorAddTest() failure was apparently due to the AMD drivers
writing past the end of a direct byte buffer in such a way that it made
System.gc() crash when called during teardown (this crash didn't even
dump stack). Making the buffer larger solved the problem.

src/com/jogamp/opencl/CLPlatform.java
test/com/jogamp/opencl/CLProgramTest.java
test/com/jogamp/opencl/LowLevelBindingTest.java

index b7b7389..95e0233 100644 (file)
@@ -451,6 +451,12 @@ public class CLPlatform {
     }
 
     /**
+     * @return true if the vendor is AMD.
+     */
+    public boolean isVendorAMD() {
+        return getVendor().contains("Advanced Micro Devices");
+    }
+    /**
      * Returns the ICD suffix.
      */
     @CLProperty("CL_PLATFORM_ICD_SUFFIX_KHR")
index 7fb7bc3..7a56a93 100644 (file)
@@ -85,12 +85,16 @@ public class CLProgramTest extends UITestCase {
         CLContext context = CLContext.create();
         CLProgram program = context.createProgram(getClass().getResourceAsStream("testkernels.cl"));
 
-        try{
-            program.createCLKernels();
-            fail("expected exception but got none :(");
-        }catch(CLException ex) {
-            out.println("got expected exception:  "+ex.getCLErrorString());
-            assertEquals(ex.errorcode, CL.CL_INVALID_PROGRAM_EXECUTABLE);
+        // only test kernel creation error on unbuilt program if we're not on AMD -- as of
+        // 3/8/2014, AMD drivers segfault on this instead of returning CL_INVALID_PROGRAM_EXECUTABLE
+        if(!context.getPlatform().isVendorAMD()) {
+            try{
+                program.createCLKernels();
+                fail("expected exception but got none :(");
+            }catch(CLException ex) {
+                out.println("got expected exception:  "+ex.getCLErrorString());
+                assertEquals(ex.errorcode, CL.CL_INVALID_PROGRAM_EXECUTABLE);
+            }
         }
 
         out.println(program.getBuildStatus());
@@ -127,7 +131,7 @@ public class CLProgramTest extends UITestCase {
         CLProgram program = context.createProgram(getClass().getResourceAsStream("testkernels.cl"))
                                    .build(ENABLE_MAD, WARNINGS_ARE_ERRORS);
 
-        // optain binaries
+        // obtain binaries
         Map<CLDevice, byte[]> binaries = program.getBinaries();
         assertFalse(binaries.isEmpty());
 
@@ -177,11 +181,15 @@ public class CLProgramTest extends UITestCase {
         assertNotNull(program.getSource());
         assertEquals(program.getSource().length(), 0);
 
-        try{
-            Map<String, CLKernel> kernels = program.createCLKernels();
-            fail("expected an exception from createCLKernels but got: "+kernels);
-        }catch(CLException ex) {
-            // expected, not build yet
+        // only test kernel creation error on unbuilt program if we're not on AMD -- as of
+        // 3/8/2014, AMD drivers segfault on this instead of returning CL_INVALID_PROGRAM_EXECUTABLE
+        if(!context.getPlatform().isVendorAMD()) {
+            try{
+                Map<String, CLKernel> kernels = program.createCLKernels();
+                fail("expected an exception from createCLKernels but got: "+kernels);
+            }catch(CLException ex) {
+                // expected, not built yet
+            }
         }
 
         out.println(program.getBuildStatus());
index 90027e1..52d7488 100644 (file)
@@ -256,7 +256,10 @@ public class LowLevelBindingTest extends UITestCase {
         int deviceCount = (int) (longBuffer.get(0) / (is32Bit() ? 4 : 8));
         out.println("context created with " + deviceCount + " devices");
 
-        ByteBuffer bb = newDirectByteBuffer(4096);
+        // Was originally 4096, but had to make this bigger or it would crash in UITestCase.oneTimeTearDown(){ System.gc() }
+        // without even dumping a stack when using AMD drivers. Presumably the drivers would write past the end
+        // of the block and mess up GC info somehow.
+        ByteBuffer bb = newDirectByteBuffer(8192);
         ret = cl.clGetContextInfo(context, CL.CL_CONTEXT_DEVICES, bb.capacity(), bb, null);
         checkError("on clGetContextInfo", ret);
 
http://JogAmp.org git info: FAQ, tutorial and man pages.