diff --git a/src/aparapi/com.amd.aparapi/dist/aparapi.jar b/src/aparapi/com.amd.aparapi/dist/aparapi.jar index 0be74ef231d313a2b694f0ca651bdb8c5caf6e2b..44f2c68a53dacfb08499ef538b1d34bd10381558 100644 Binary files a/src/aparapi/com.amd.aparapi/dist/aparapi.jar and b/src/aparapi/com.amd.aparapi/dist/aparapi.jar differ diff --git a/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/Kernel.java b/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/Kernel.java index 2d11bcce22f037ca2f3653ff72d0588de4303590..81da69de464585bb5387170d8e32b21d33412d17 100644 --- a/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/Kernel.java +++ b/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/Kernel.java @@ -994,7 +994,23 @@ public abstract class Kernel implements Cloneable { } } + /** + * Init a kernel from an existing one. used in caching mechanisems to improve startup time (ex. SparkCL). + * + */ + public void init(Kernel kernel) { + + // create and init a copy of the kernel runner + kernelRunner = new KernelRunner(this); + if(kernel.kernelRunner!=null) + kernelRunner.init(kernel.kernelRunner); + // We need to be careful to also clone the KernelState + kernelState = new KernelState(kernel.kernelState); // Qualified copy constructor + } + + +/** * Delegates to either {@link java.lang.Math#acos(double)} (Java) or <code><a href="http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/acos.html">acos(float)</a></code> (OpenCL). * * User should note the differences in precision between Java and OpenCL's implementation of arithmetic functions to determine whether the difference in precision is acceptable. diff --git a/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/KernelRunnerJNI.java b/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/KernelRunnerJNI.java index da60ff634120a890eeeebf3a6315e69de3c7e395..b8039bd8632316e3f0f2bee26f89e30fb9efca82 100644 --- a/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/KernelRunnerJNI.java +++ b/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/internal/jni/KernelRunnerJNI.java @@ -310,6 +310,8 @@ public abstract class KernelRunnerJNI{ //protected native long buildProgramJNI(long _jniContextHandle, String _source); // !!! oren change -> add binary option to build + // !!! oren change -> add synchronized + // protected native synchronized long buildProgramJNI(long _jniContextHandle, String _source, int _buildFlags); protected native long buildProgramJNI(long _jniContextHandle, String _source, int _buildFlags); protected native int setArgsJNI(long _jniContextHandle, KernelArgJNI[] _args, int argc); diff --git a/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelRunner.java b/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelRunner.java index c8578a9bc6ccaac8631a2e36cb2fbec19826b29c..4ecec0d710b1c56ed6591ea5b210903c4bb27495 100644 --- a/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelRunner.java +++ b/src/aparapi/com.amd.aparapi/src/java/com/amd/aparapi/internal/kernel/KernelRunner.java @@ -110,7 +110,21 @@ public class KernelRunner extends KernelRunnerJNI{ kernel = _kernel; } - /** + public void init(KernelRunner kernelRunner) + { + //this = super.clone(); + jniContextHandle = kernelRunner.jniContextHandle; + entryPoint = kernelRunner.entryPoint; + argc = kernelRunner.argc; + args = kernelRunner.args; + //puts = kernelRunner.puts; + capabilitiesSet = kernelRunner.capabilitiesSet; + accumulatedExecutionTime = kernelRunner.accumulatedExecutionTime; + conversionTime = kernelRunner.conversionTime; + executionTime = kernelRunner.executionTime; + } + +/** * <code>Kernel.dispose()</code> delegates to <code>KernelRunner.dispose()</code> which delegates to <code>disposeJNI()</code> to actually close JNI data structures.<br/> * * @see KernelRunner#disposeJNI() @@ -1021,8 +1035,12 @@ public class KernelRunner extends KernelRunnerJNI{ } String openCL = null; - try { - openCL = KernelWriter.writeToString(entryPoint); + try { + // !!! oren change -> kernel writer is not thread safe! + // TODO: check if it makes sense to change this + synchronized (Kernel.class) { + openCL = KernelWriter.writeToString(entryPoint); + } } catch (final CodeGenException codeGenException) { return warnFallBackAndExecute(_entrypointName, _range, _passes, codeGenException); } @@ -1050,10 +1068,15 @@ public class KernelRunner extends KernelRunnerJNI{ // !!! oren change -> support flow types // set flow type int buildFlags = kernel.getFlowType().getValue(); - // Send the string to OpenCL to compile it - if (buildProgramJNI(jniContextHandle, openCL,buildFlags) == 0) { + // Send the string to OpenCL to compile it + // !!! oren change -> in a parallel device for singel kernel environment buildProgramJNI can fail + // TODO: improve sync to be more fine grained later - reuse kernel elements better etc. + //synchronized (Kernel.class) + //{ + if (buildProgramJNI(jniContextHandle, openCL,buildFlags) == 0) { return warnFallBackAndExecute(_entrypointName, _range, _passes, "OpenCL compile failed"); - } + } + //} args = new KernelArg[entryPoint.getReferencedFields().size()]; int i = 0; diff --git a/src/aparapi/samples/add/src/com/amd/aparapi/sample/add/MainSelectPlatform.java b/src/aparapi/samples/add/src/com/amd/aparapi/sample/add/MainSelectPlatform.java index 053483ef860404f82a66a9874f93dd513f6123d7..243a26713fa3f19bfab252922fc970d524995ae0 100644 --- a/src/aparapi/samples/add/src/com/amd/aparapi/sample/add/MainSelectPlatform.java +++ b/src/aparapi/samples/add/src/com/amd/aparapi/sample/add/MainSelectPlatform.java @@ -227,6 +227,9 @@ public class MainSelectPlatform { Device device = Device.getDevice(platformHint,deviceType,deviceId); kernel.execute(Range.create(device,512,16)); System.out.printf("****************\n"); + + // test new range functionality + Range.create(device,Range.create(512,16));