From 7a7f87a1fc7419f758ba9b134764ae544fd6d566 Mon Sep 17 00:00:00 2001 From: Wade Walker Date: Sat, 8 Mar 2014 16:17:36 -0600 Subject: Fix crashes due to AMD driver bugs. 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 | 6 +++++ test/com/jogamp/opencl/CLProgramTest.java | 32 +++++++++++++++---------- test/com/jogamp/opencl/LowLevelBindingTest.java | 5 +++- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/com/jogamp/opencl/CLPlatform.java b/src/com/jogamp/opencl/CLPlatform.java index b7b7389c..95e02333 100644 --- a/src/com/jogamp/opencl/CLPlatform.java +++ b/src/com/jogamp/opencl/CLPlatform.java @@ -450,6 +450,12 @@ public class CLPlatform { return getInfoString(CL_PLATFORM_VENDOR); } + /** + * @return true if the vendor is AMD. + */ + public boolean isVendorAMD() { + return getVendor().contains("Advanced Micro Devices"); + } /** * Returns the ICD suffix. */ diff --git a/test/com/jogamp/opencl/CLProgramTest.java b/test/com/jogamp/opencl/CLProgramTest.java index 7fb7bc32..7a56a939 100644 --- a/test/com/jogamp/opencl/CLProgramTest.java +++ b/test/com/jogamp/opencl/CLProgramTest.java @@ -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 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 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 kernels = program.createCLKernels(); + fail("expected an exception from createCLKernels but got: "+kernels); + }catch(CLException ex) { + // expected, not built yet + } } out.println(program.getBuildStatus()); diff --git a/test/com/jogamp/opencl/LowLevelBindingTest.java b/test/com/jogamp/opencl/LowLevelBindingTest.java index 90027e13..52d74882 100644 --- a/test/com/jogamp/opencl/LowLevelBindingTest.java +++ b/test/com/jogamp/opencl/LowLevelBindingTest.java @@ -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); -- cgit v1.2.3