From d4f04ddd3ef3b65b7c31d3504cf55489153c60c1 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 21 Feb 2014 08:37:26 +0100 Subject: Bug 979: Add 'CL_DEVICE_MEM_BASE_ADDR_ALIGN' to CLDevice and overal maximum to CLContext - Split CLBufferTest and use alignment. See Bug 979 for remaining issues and discussion. --- src/com/jogamp/opencl/CLContext.java | 11 +++ src/com/jogamp/opencl/CLDevice.java | 13 +++- src/com/jogamp/opencl/impl/CLTLInfoAccessor.java | 10 ++- src/com/jogamp/opencl/spi/CLInfoAccessor.java | 8 +- test/com/jogamp/opencl/CLBufferTest.java | 94 ++++++++++++++++-------- test/com/jogamp/opencl/HighLevelBindingTest.java | 1 + 6 files changed, 101 insertions(+), 36 deletions(-) diff --git a/src/com/jogamp/opencl/CLContext.java b/src/com/jogamp/opencl/CLContext.java index 163375eb..378f42f9 100644 --- a/src/com/jogamp/opencl/CLContext.java +++ b/src/com/jogamp/opencl/CLContext.java @@ -627,6 +627,17 @@ public class CLContext extends CLObjectResource { return CLPlatform.findMaxFlopsDevice(getDevices(), type); } + /** + * Returns the maximum {@link CLDevice#getMemBaseAddrAlign()} of all devices. + */ + public long getMaxMemBaseAddrAlign() { + long maxAlignment = 0; + for (CLDevice device : getDevices()) { + maxAlignment = Math.max(maxAlignment, device.getMemBaseAddrAlign()); + } + return maxAlignment; + } + /** * Returns all devices associated with this CLContext. */ diff --git a/src/com/jogamp/opencl/CLDevice.java b/src/com/jogamp/opencl/CLDevice.java index 25fb009f..860fa1a0 100644 --- a/src/com/jogamp/opencl/CLDevice.java +++ b/src/com/jogamp/opencl/CLDevice.java @@ -48,7 +48,7 @@ import static com.jogamp.opencl.llb.CL.*; * @see CLPlatform#getMaxFlopsDevice(com.jogamp.opencl.CLDevice.Type...) * @see CLContext#getDevices() * @see CLContext#getMaxFlopsDevice(com.jogamp.opencl.CLDevice.Type) - * @author Michael Bien + * @author Michael Bien, et al. */ public class CLDevice extends CLObject { @@ -356,7 +356,16 @@ public class CLDevice extends CLObject { */ @CLProperty("CL_DEVICE_MAX_MEM_ALLOC_SIZE") public long getMaxMemAllocSize() { - return deviceInfo.getLong(CL_DEVICE_MAX_MEM_ALLOC_SIZE); + return deviceInfo.getLong(CL.CL_DEVICE_MAX_MEM_ALLOC_SIZE); + } + + /** + * Returns the uint32_t memory base address alignment + * value reinterpreted as a long value. + */ + @CLProperty("CL_DEVICE_MEM_BASE_ADDR_ALIGN") + public long getMemBaseAddrAlign() { + return deviceInfo.getUInt32Long(CL.CL_DEVICE_MEM_BASE_ADDR_ALIGN); } /** diff --git a/src/com/jogamp/opencl/impl/CLTLInfoAccessor.java b/src/com/jogamp/opencl/impl/CLTLInfoAccessor.java index c31b22a6..28115305 100644 --- a/src/com/jogamp/opencl/impl/CLTLInfoAccessor.java +++ b/src/com/jogamp/opencl/impl/CLTLInfoAccessor.java @@ -41,7 +41,7 @@ import static com.jogamp.opencl.CLException.*; /** * Internal utility for common OpenCL clGetFooInfo calls. * Threadsafe, threadlocal implementation. - * @author Michael Bien + * @author Michael Bien, et al. */ public abstract class CLTLInfoAccessor implements CLInfoAccessor { @@ -64,6 +64,14 @@ public abstract class CLTLInfoAccessor implements CLInfoAccessor { }; + @Override + public final long getUInt32Long(int key) { + final ByteBuffer buffer = getBB(4).putInt(0, 0); + final int ret = getInfo(key, 4, buffer, null); + CLException.checkForError(ret, "error while asking for info value"); + return Bitstream.toUInt32Long(buffer.getInt(0)); + } + @Override public final long getLong(int key) { diff --git a/src/com/jogamp/opencl/spi/CLInfoAccessor.java b/src/com/jogamp/opencl/spi/CLInfoAccessor.java index 0ff0aeac..a02a38e8 100644 --- a/src/com/jogamp/opencl/spi/CLInfoAccessor.java +++ b/src/com/jogamp/opencl/spi/CLInfoAccessor.java @@ -6,12 +6,18 @@ package com.jogamp.opencl.spi; /** * Internal utility for common OpenCL clGetFooInfo calls. * Provides common accessors to CL objects. - * @author Michael Bien + * @author Michael Bien, et al. */ public interface CLInfoAccessor { int[] getInts(int key, int n); + /** + * Returns the uint32_t value for the given key, + * reinterpreted as a long value. + */ + long getUInt32Long(int key); + /** * Returns the long value for the given key. */ diff --git a/test/com/jogamp/opencl/CLBufferTest.java b/test/com/jogamp/opencl/CLBufferTest.java index 0638844d..5b5d0e38 100644 --- a/test/com/jogamp/opencl/CLBufferTest.java +++ b/test/com/jogamp/opencl/CLBufferTest.java @@ -32,6 +32,7 @@ import com.jogamp.opencl.CLMemory.Mem; import com.jogamp.opencl.CLMemory.Map; import com.jogamp.opencl.test.util.UITestCase; import com.jogamp.common.nio.Buffers; +import com.jogamp.common.util.Bitstream; import java.io.IOException; import java.nio.Buffer; @@ -247,7 +248,7 @@ public class CLBufferTest extends UITestCase { } @Test - public void subBufferTest() { + public void subBufferTest01ByteBuffer() { out.println(" - - - subBufferTest - - - "); @@ -260,48 +261,77 @@ public class CLBufferTest extends UITestCase { CLContext context = CLContext.create(platform); try{ final int subelements = 5; + final long lMaxAlignment = context.getMaxMemBaseAddrAlign(); + final int iMaxAlignment = Bitstream.uint32LongToInt(lMaxAlignment); + System.err.println("XXX: maxAlignment "+lMaxAlignment+", 0x"+Long.toHexString(lMaxAlignment)+", (int)"+iMaxAlignment+", (int)0x"+Integer.toHexString(iMaxAlignment)); + if( -1 == iMaxAlignment ) { + throw new RuntimeException("Cannot handle MaxMemBaseAddrAlign > MAX_INT, has 0x"+Long.toHexString(lMaxAlignment)); + } // device only - { - CLBuffer buffer = context.createBuffer(64); + CLBuffer buffer = context.createBuffer(iMaxAlignment+subelements); - assertFalse(buffer.isSubBuffer()); - assertNotNull(buffer.getSubBuffers()); - assertTrue(buffer.getSubBuffers().isEmpty()); + assertFalse(buffer.isSubBuffer()); + assertNotNull(buffer.getSubBuffers()); + assertTrue(buffer.getSubBuffers().isEmpty()); - CLSubBuffer subBuffer = buffer.createSubBuffer(10, subelements); + CLSubBuffer subBuffer = buffer.createSubBuffer(iMaxAlignment, subelements); - assertTrue(subBuffer.isSubBuffer()); - assertEquals(subelements, subBuffer.getCLSize()); - assertEquals(10, subBuffer.getOffset()); - assertEquals(10, subBuffer.getCLOffset()); - assertEquals(buffer, subBuffer.getParent()); - assertEquals(1, buffer.getSubBuffers().size()); + assertTrue(subBuffer.isSubBuffer()); + assertEquals(subelements, subBuffer.getCLSize()); + assertEquals(iMaxAlignment, subBuffer.getOffset()); + assertEquals(iMaxAlignment, subBuffer.getCLOffset()); + assertEquals(buffer, subBuffer.getParent()); + assertEquals(1, buffer.getSubBuffers().size()); - subBuffer.release(); - assertEquals(0, buffer.getSubBuffers().size()); - } + subBuffer.release(); + assertEquals(0, buffer.getSubBuffers().size()); + }finally{ + context.release(); + } - // device + direct buffer - { - CLBuffer buffer = context.createFloatBuffer(64); - assertFalse(buffer.isSubBuffer()); - assertNotNull(buffer.getSubBuffers()); - assertTrue(buffer.getSubBuffers().isEmpty()); + } - CLSubBuffer subBuffer = buffer.createSubBuffer(10, subelements); + @Test + public void subBufferTest02FloatBuffer() { - assertTrue(subBuffer.isSubBuffer()); - assertEquals(subelements, subBuffer.getBuffer().capacity()); - assertEquals(10, subBuffer.getOffset()); - assertEquals(40, subBuffer.getCLOffset()); - assertEquals(buffer, subBuffer.getParent()); - assertEquals(1, buffer.getSubBuffers().size()); + out.println(" - - - subBufferTest - - - "); - assertEquals(subBuffer.getCLCapacity(), subBuffer.getBuffer().capacity()); + CLPlatform platform = CLPlatform.getDefault(version(CL_1_1)); + if(platform == null) { + out.println("aborting subBufferTest"); + return; + } - subBuffer.release(); - assertEquals(0, buffer.getSubBuffers().size()); + CLContext context = CLContext.create(platform); + try{ + final int subelements = 5; + final long lMaxAlignment = context.getMaxMemBaseAddrAlign(); + final int iMaxAlignment = Bitstream.uint32LongToInt(lMaxAlignment); + System.err.println("XXX: maxAlignment "+lMaxAlignment+", 0x"+Long.toHexString(lMaxAlignment)+", (int)"+iMaxAlignment+", (int)0x"+Integer.toHexString(iMaxAlignment)); + if( -1 == iMaxAlignment ) { + throw new RuntimeException("Cannot handle MaxMemBaseAddrAlign > MAX_INT, has 0x"+Long.toHexString(lMaxAlignment)); } + // FIXME: See Bug 979: Offset/Alignment via offset calculation per element-count is faulty! + final int floatsPerAlignment = iMaxAlignment / Buffers.SIZEOF_FLOAT; + // device + direct buffer + CLBuffer buffer = context.createFloatBuffer(floatsPerAlignment+subelements); + assertFalse(buffer.isSubBuffer()); + assertNotNull(buffer.getSubBuffers()); + assertTrue(buffer.getSubBuffers().isEmpty()); + + CLSubBuffer subBuffer = buffer.createSubBuffer(floatsPerAlignment, subelements); + + assertTrue(subBuffer.isSubBuffer()); + assertEquals(subelements, subBuffer.getBuffer().capacity()); + assertEquals(floatsPerAlignment, subBuffer.getOffset()); + assertEquals(iMaxAlignment, subBuffer.getCLOffset()); + assertEquals(buffer, subBuffer.getParent()); + assertEquals(1, buffer.getSubBuffers().size()); + + assertEquals(subBuffer.getCLCapacity(), subBuffer.getBuffer().capacity()); + + subBuffer.release(); + assertEquals(0, buffer.getSubBuffers().size()); }finally{ context.release(); diff --git a/test/com/jogamp/opencl/HighLevelBindingTest.java b/test/com/jogamp/opencl/HighLevelBindingTest.java index 6dd6a73f..40d2b9ed 100644 --- a/test/com/jogamp/opencl/HighLevelBindingTest.java +++ b/test/com/jogamp/opencl/HighLevelBindingTest.java @@ -164,6 +164,7 @@ public class HighLevelBindingTest extends UITestCase { // out.println(" C version: "+device.getCVersion()); //CL 1.1 out.println(" driver version: "+device.getDriverVersion()); out.println(" type: "+device.getType()); + out.println(" mem base addr align: "+device.getMemBaseAddrAlign()); out.println(" global mem: "+device.getGlobalMemSize()/(1024*1024)+" MB"); out.println(" max alloc mem: "+device.getMaxMemAllocSize()/(1024*1024)+" MB"); out.println(" max param size: "+device.getMaxParameterSize()+" byte"); -- cgit v1.2.3