diff options
-rw-r--r-- | resources/cl-if.cfg | 1 | ||||
-rw-r--r-- | resources/clImplCustomCode.c | 2 | ||||
-rw-r--r-- | resources/clImplCustomCode.java | 12 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLProgram.java | 84 | ||||
-rw-r--r-- | src/com/jogamp/opencl/CLProgramBuilder.java | 15 | ||||
-rw-r--r-- | src/com/jogamp/opencl/impl/BuildProgramCallback.java (renamed from src/com/jogamp/opencl/BuildProgramCallback.java) | 4 | ||||
-rw-r--r-- | src/com/jogamp/opencl/util/CLBuildConfiguration.java | 7 | ||||
-rw-r--r-- | src/com/jogamp/opencl/util/CLBuildListener.java | 25 | ||||
-rw-r--r-- | src/com/jogamp/opencl/util/CLProgramConfiguration.java | 6 | ||||
-rw-r--r-- | test/com/jogamp/opencl/CLCommandQueueTest.java | 11 | ||||
-rw-r--r-- | test/com/jogamp/opencl/CLProgramTest.java | 23 | ||||
-rw-r--r-- | test/com/jogamp/opencl/LowLevelBindingTest.java | 1 |
12 files changed, 163 insertions, 28 deletions
diff --git a/resources/cl-if.cfg b/resources/cl-if.cfg index cbf2d9b8..d0413d97 100644 --- a/resources/cl-if.cfg +++ b/resources/cl-if.cfg @@ -6,6 +6,7 @@ Style InterfaceOnly Import java.nio.IntBuffer Import java.nio.LongBuffer Import com.jogamp.opencl.impl.CLImageFormatImpl +import com.jogamp.opencl.impl.BuildProgramCallback; ClassJavadoc CL /** ClassJavadoc CL * Java bindings to OpenCL, the Open Computing Language. diff --git a/resources/clImplCustomCode.c b/resources/clImplCustomCode.c index eb209157..b491eb7f 100644 --- a/resources/clImplCustomCode.c +++ b/resources/clImplCustomCode.c @@ -24,7 +24,7 @@ JNI_OnLoad(JavaVM * _jvm, void *reserved) { } // throws ClassNotFoundException (or other reflection stuff) - jclass buildCBClassID = (*env)->FindClass(env, "com/jogamp/opencl/BuildProgramCallback"); + jclass buildCBClassID = (*env)->FindClass(env, "com/jogamp/opencl/impl/BuildProgramCallback"); jclass errorHandlerClassID = (*env)->FindClass(env, "com/jogamp/opencl/CreateContextCallback"); // throws even more reflection Exceptions diff --git a/resources/clImplCustomCode.java b/resources/clImplCustomCode.java index b5b5ec61..f3daddf0 100644 --- a/resources/clImplCustomCode.java +++ b/resources/clImplCustomCode.java @@ -44,12 +44,12 @@ /** Interface to C language function: <br> <code> void * {@native clEnqueueMapImage}(cl_command_queue command_queue, cl_mem image, uint32_t blocking_map, uint64_t map_flags, const size_t * , const size_t * , size_t * image_row_pitch, size_t * image_slice_pitch, uint32_t num_events_in_wait_list, cl_event * event_wait_list, cl_event * event, int32_t * errcode_ret); </code> - @param origin a direct {@link com.jogamp.gluegen.runtime.PointerBuffer} - @param range a direct {@link com.jogamp.gluegen.runtime.PointerBuffer} - @param image_row_pitch a direct {@link com.jogamp.gluegen.runtime.PointerBuffer} - @param image_slice_pitch a direct {@link com.jogamp.gluegen.runtime.PointerBuffer} - @param event_wait_list a direct {@link com.jogamp.gluegen.runtime.PointerBuffer} - @param event a direct {@link com.jogamp.gluegen.runtime.PointerBuffer} + @param origin a direct {@link com.jogamp.common.nio.PointerBuffer} + @param range a direct {@link com.jogamp.common.nio.PointerBuffer} + @param image_row_pitch a direct {@link com.jogamp.common.nio.PointerBuffer} + @param image_slice_pitch a direct {@link com.jogamp.common.nio.PointerBuffer} + @param event_wait_list a direct {@link com.jogamp.common.nio.PointerBuffer} + @param event a direct {@link com.jogamp.common.nio.PointerBuffer} @param errcode_ret a direct {@link java.nio.IntBuffer} */ public java.nio.ByteBuffer clEnqueueMapImage(long command_queue, long image, int blocking_map, long map_flags, Int64Buffer origin, Int64Buffer range, diff --git a/src/com/jogamp/opencl/CLProgram.java b/src/com/jogamp/opencl/CLProgram.java index 43fd9665..b6c1d7a2 100644 --- a/src/com/jogamp/opencl/CLProgram.java +++ b/src/com/jogamp/opencl/CLProgram.java @@ -5,6 +5,8 @@ import com.jogamp.opencl.util.CLUtil; import com.jogamp.common.nio.Int64Buffer; import com.jogamp.common.os.Platform; import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.opencl.impl.BuildProgramCallback; +import com.jogamp.opencl.util.CLBuildListener; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.Collections; @@ -179,17 +181,40 @@ public class CLProgram extends CLObject implements CLResource { * @return this */ public CLProgram build() { - build(null, (CLDevice[])null); + build(null, (String)null, (CLDevice[]) null); + return this; + } + + /** + * Builds this program for all devices associated with the context. + * @see CLBuildListener + * @param listener A listener who is notified when the program was built. + * @return this + */ + public CLProgram build(CLBuildListener listener) { + build(listener, null, (CLDevice[])null); return this; } /** * Builds this program for the given devices. - * @return this * @param devices A list of devices this program should be build on or null for all devices of its context. + * @return this */ public CLProgram build(CLDevice... devices) { - build(null, devices); + build(null, (String) null, devices); + return this; + } + + /** + * Builds this program for the given devices. + * @see CLBuildListener + * @param listener A listener who is notified when the program was built. + * @param devices A list of devices this program should be build on or null for all devices of its context. + * @return this + */ + public CLProgram build(CLBuildListener listener, CLDevice... devices) { + build(listener,null, devices); return this; } @@ -199,17 +224,39 @@ public class CLProgram extends CLObject implements CLResource { * @return this */ public CLProgram build(String options) { - build(options, (CLDevice[])null); + build(null, options, (CLDevice[])null); return this; } /** * Builds this program for all devices associated with the context using the specified build options. * @see CompilerOptions + * @see CLBuildListener + * @param listener A listener who is notified when the program was built. * @return this */ + public CLProgram build(CLBuildListener listener, String options) { + build(listener, options, (CLDevice[])null); + return this; + } + + /** + * Builds this program for all devices associated with the context using the specified build options. + * @see CompilerOptions + */ public CLProgram build(String... options) { - build(optionsOf(options), (CLDevice[])null); + build(null, optionsOf(options), (CLDevice[])null); + return this; + } + + /** + * Builds this program for all devices associated with the context using the specified build options. + * @see CompilerOptions + * @see CLBuildListener + * @param listener A listener who is notified when the program was built. + */ + public CLProgram build(CLBuildListener listener, String... options) { + build(listener, optionsOf(options), (CLDevice[])null); return this; } @@ -217,10 +264,24 @@ public class CLProgram extends CLObject implements CLResource { * Builds this program for the given devices and with the specified build options. In case this program was * already built and there are kernels associated with this program they will be released first before rebuild. * @see CompilerOptions - * @return this * @param devices A list of devices this program should be build on or null for all devices of its context. + * @return this */ public CLProgram build(String options, CLDevice... devices) { + build(null, options, devices); + return this; + } + + /** + * Builds this program for the given devices and with the specified build options. In case this program was + * already built and there are kernels associated with this program they will be released first before rebuild. + * @see CompilerOptions + * @see CLBuildListener + * @return this + * @param devices A list of devices this program should be build on or null for all devices of its context. + * @param listener A listener who is notified when the program was built. + */ + public CLProgram build(final CLBuildListener listener, String options, CLDevice... devices) { if(released) { throw new CLException("can not build a released program"); @@ -252,11 +313,20 @@ public class CLProgram extends CLObject implements CLResource { buildStatusMap = null; executable = false; + BuildProgramCallback callback = null; + if(listener != null) { + callback = new BuildProgramCallback() { + public void buildFinished(long cl_program) { + listener.buildFinished(CLProgram.this); + } + }; + } + // Build the program int ret = 0; // building programs is not threadsafe // synchronized(buildLock) { - ret = cl.clBuildProgram(ID, count, deviceIDs, options, null); + ret = cl.clBuildProgram(ID, count, deviceIDs, options, callback); // } if(ret != CL_SUCCESS) { diff --git a/src/com/jogamp/opencl/CLProgramBuilder.java b/src/com/jogamp/opencl/CLProgramBuilder.java index 855d9837..e9440755 100644 --- a/src/com/jogamp/opencl/CLProgramBuilder.java +++ b/src/com/jogamp/opencl/CLProgramBuilder.java @@ -1,6 +1,7 @@ package com.jogamp.opencl; import com.jogamp.opencl.util.CLBuildConfiguration; +import com.jogamp.opencl.util.CLBuildListener; import com.jogamp.opencl.util.CLProgramConfiguration; import java.io.IOException; import java.io.ObjectInputStream; @@ -178,11 +179,21 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa @Override public CLProgram build() { - return build(program); + return build(program, null); + } + + @Override + public CLProgram build(CLBuildListener listener) { + return build(program, listener); } @Override public CLProgram build(CLProgram program) { + return build(program, null); + } + + @Override + public CLProgram build(CLProgram program, CLBuildListener listener) { if(program == null) { throw new NullPointerException("no program has been set"); } @@ -191,7 +202,7 @@ public final class CLProgramBuilder implements CLProgramConfiguration, Serializa setup.addAll(defineSet); String options = CLProgram.optionsOf(setup.toArray(new String[setup.size()])); CLDevice[] devices = binariesMap.keySet().toArray(new CLDevice[binariesMap.size()]); - return program.build(options, devices); + return program.build(listener, options, devices); } @Override diff --git a/src/com/jogamp/opencl/BuildProgramCallback.java b/src/com/jogamp/opencl/impl/BuildProgramCallback.java index c37891ec..e4d68a4f 100644 --- a/src/com/jogamp/opencl/BuildProgramCallback.java +++ b/src/com/jogamp/opencl/impl/BuildProgramCallback.java @@ -1,4 +1,4 @@ -package com.jogamp.opencl; +package com.jogamp.opencl.impl; /** * A callback an application can register to be called when the program executable @@ -6,7 +6,7 @@ package com.jogamp.opencl; * Note1: registering a build callback can make {@link CL#clBuildProgram} non blocking (OpenCL implementation dependent).<br/> * Note2: the thread which calls this method is unspecified. The Application should ensure propper synchronization. * @author Michael Bien - * @see CL#clBuildProgram(long, int, com.jogamp.common.nio.PointerBuffer, java.lang.String, com.jogamp.opencl.BuildProgramCallback) + * @see com.jogamp.opencl.CL#clBuildProgram(long, int, com.jogamp.common.nio.PointerBuffer, java.lang.String, com.jogamp.opencl.impl.BuildProgramCallback) */ public interface BuildProgramCallback { diff --git a/src/com/jogamp/opencl/util/CLBuildConfiguration.java b/src/com/jogamp/opencl/util/CLBuildConfiguration.java index 1de62637..7019f1d2 100644 --- a/src/com/jogamp/opencl/util/CLBuildConfiguration.java +++ b/src/com/jogamp/opencl/util/CLBuildConfiguration.java @@ -21,6 +21,13 @@ public interface CLBuildConfiguration extends Cloneable { public CLProgram build(CLProgram program); /** + * Builds or rebuilds the program. + * @param program The program which should be build. + * @param listener The callback who is notified when the program has built. + */ + public CLProgram build(CLProgram program, CLBuildListener listener); + + /** * Sets the program which should be build. */ public CLProgramConfiguration setProgram(CLProgram program); diff --git a/src/com/jogamp/opencl/util/CLBuildListener.java b/src/com/jogamp/opencl/util/CLBuildListener.java new file mode 100644 index 00000000..04769bb2 --- /dev/null +++ b/src/com/jogamp/opencl/util/CLBuildListener.java @@ -0,0 +1,25 @@ +/* + * Sunday, May 02 2010 20:38 + */ + +package com.jogamp.opencl.util; + +import com.jogamp.opencl.CLProgram; + +/** + * A callback an application can register to be called when the program executable + * has been built (successfully or unsuccessfully).<br/> + * Note1: registering a build callback can make {@link CL#clBuildProgram} non blocking (OpenCL implementation dependent).<br/> + * Note2: the thread which calls this method is unspecified. The Application should ensure propper synchronization. + * @author Michael Bien + * @see com.jogamp.opencl.CL#clBuildProgram(long, int, com.jogamp.common.nio.PointerBuffer, java.lang.String, com.jogamp.opencl.impl.BuildProgramCallback) + */ +public interface CLBuildListener { + + /** + * Called when the program executable + * has been built (successfully or unsuccessfully). + */ + public void buildFinished(CLProgram program); + +} diff --git a/src/com/jogamp/opencl/util/CLProgramConfiguration.java b/src/com/jogamp/opencl/util/CLProgramConfiguration.java index 901e28ce..de80376b 100644 --- a/src/com/jogamp/opencl/util/CLProgramConfiguration.java +++ b/src/com/jogamp/opencl/util/CLProgramConfiguration.java @@ -21,6 +21,12 @@ public interface CLProgramConfiguration extends CLBuildConfiguration { public CLProgram build(); /** + * Builds or rebuilds a program. + * @param listener The callback who will be notified when the program has built. + */ + public CLProgram build(CLBuildListener listener); + + /** * Returns the program. */ public CLProgram getProgram(); diff --git a/test/com/jogamp/opencl/CLCommandQueueTest.java b/test/com/jogamp/opencl/CLCommandQueueTest.java index e2da5665..9070b268 100644 --- a/test/com/jogamp/opencl/CLCommandQueueTest.java +++ b/test/com/jogamp/opencl/CLCommandQueueTest.java @@ -172,6 +172,7 @@ public class CLCommandQueueTest { CLDevice[] devices = context.getDevices(); + // ignore this test if we can't test in parallel if (devices.length < 2) { out.println("aborting test... need at least 2 devices"); context.release(); @@ -188,22 +189,18 @@ public class CLCommandQueueTest { CLProgram program = context.createProgram(getClass().getResourceAsStream("testkernels.cl")).build(); + //two independent kernel instances final CLKernel vectorAddKernel1 = program.createCLKernel("VectorAddGM").setArg(3, elements); final CLKernel vectorAddKernel2 = program.createCLKernel("VectorAddGM").setArg(3, elements); - int secondDevice = devices.length > 1 ? 1 : 0; - - final CLCommandQueue queue1 = devices[0 ].createCommandQueue(); - final CLCommandQueue queue2 = devices[secondDevice].createCommandQueue(); + final CLCommandQueue queue1 = devices[0].createCommandQueue(); + final CLCommandQueue queue2 = devices[1].createCommandQueue(); out.println(queue1); out.println(queue2); fillBuffer(clBufferC.buffer, 12345); - if (secondDevice > 0) { - System.out.println("using two devices"); - } final MultiQueueBarrier barrier = new MultiQueueBarrier(2); diff --git a/test/com/jogamp/opencl/CLProgramTest.java b/test/com/jogamp/opencl/CLProgramTest.java index 35dbde4b..ec238fb5 100644 --- a/test/com/jogamp/opencl/CLProgramTest.java +++ b/test/com/jogamp/opencl/CLProgramTest.java @@ -3,6 +3,7 @@ package com.jogamp.opencl; import com.jogamp.opencl.util.CLBuildConfiguration; import com.jogamp.opencl.util.CLProgramConfiguration; import com.jogamp.opencl.CLProgram.Status; +import com.jogamp.opencl.util.CLBuildListener; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -10,6 +11,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Map; +import java.util.concurrent.CountDownLatch; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -158,7 +160,7 @@ public class CLProgramTest { } @Test - public void builderTest() throws IOException, ClassNotFoundException { + public void builderTest() throws IOException, ClassNotFoundException, InterruptedException { out.println(" - - - CLProgramTest; program builder test - - - "); CLContext context = CLContext.create(); @@ -187,8 +189,23 @@ public class CLProgramTest { .withDefine("ENABLE_FOOBAR"); out.println(builder); - - builder.setProgram(program).build(); + + // async build test + { + final CountDownLatch countdown = new CountDownLatch(1); + final CLProgram outerProgram = program; + + CLBuildListener buildCallback = new CLBuildListener() { + public void buildFinished(CLProgram program) { + assertEquals(outerProgram, program); + countdown.countDown(); + } + }; + + builder.setProgram(program).build(buildCallback); + countdown.await(); + } + assertTrue(program.isExecutable()); // serialization test diff --git a/test/com/jogamp/opencl/LowLevelBindingTest.java b/test/com/jogamp/opencl/LowLevelBindingTest.java index eb1d7bd4..2d6ea08f 100644 --- a/test/com/jogamp/opencl/LowLevelBindingTest.java +++ b/test/com/jogamp/opencl/LowLevelBindingTest.java @@ -1,5 +1,6 @@ package com.jogamp.opencl; +import com.jogamp.opencl.impl.BuildProgramCallback; import com.jogamp.common.nio.Int64Buffer; import com.jogamp.common.nio.PointerBuffer; import com.jogamp.opencl.impl.CLImpl; |