Browse Source

implemented kernel execution

shamanDevel 9 years ago
parent
commit
ecda9135ad

+ 3 - 3
jme3-core/src/main/java/com/jme3/opencl/Kernel.java

@@ -41,8 +41,8 @@ import java.nio.ByteBuffer;
  * @author Sebastian Weiss
  * @author Sebastian Weiss
  */
  */
 public abstract class Kernel {
 public abstract class Kernel {
-    private final WorkSize globalWorkSize;
-    private final WorkSize workGroupSize;
+    protected final WorkSize globalWorkSize;
+    protected final WorkSize workGroupSize;
 
 
     protected Kernel() {
     protected Kernel() {
         this.globalWorkSize = new WorkSize(0);
         this.globalWorkSize = new WorkSize(0);
@@ -94,7 +94,7 @@ public abstract class Kernel {
     }
     }
 
 
     public void setWorkGroupSizeToNull() {
     public void setWorkGroupSizeToNull() {
-        workGroupSize.set(1, 0);
+        workGroupSize.set(1, 0, 0, 0);
     }
     }
 
 
     public abstract void setArg(int index, LocalMemPerElement t);
     public abstract void setArg(int index, LocalMemPerElement t);

+ 7 - 7
jme3-core/src/main/java/com/jme3/opencl/WorkSize.java

@@ -39,9 +39,9 @@ import java.util.Arrays;
  */
  */
 public final class WorkSize {
 public final class WorkSize {
 	private int dimension;
 	private int dimension;
-	private int[] sizes;
+	private long[] sizes;
 	
 	
-	public WorkSize(int dimension, int... sizes)
+	public WorkSize(int dimension, long... sizes)
 	{
 	{
 		set(dimension, sizes);
 		set(dimension, sizes);
 	}
 	}
@@ -49,24 +49,24 @@ public final class WorkSize {
 	public WorkSize() {
 	public WorkSize() {
 		this(1, 1, 1, 1);
 		this(1, 1, 1, 1);
 	}
 	}
-	public WorkSize(int size) {
+	public WorkSize(long size) {
 		this(1, size, 1, 1);
 		this(1, size, 1, 1);
 	}
 	}
-	public WorkSize(int width, int height) {
+	public WorkSize(long width, long height) {
 		this(2, width, height, 1);
 		this(2, width, height, 1);
 	}
 	}
-	public WorkSize(int width, int height, int depth) {
+	public WorkSize(long width, long height, long depth) {
 		this(3, width, height, depth);
 		this(3, width, height, depth);
 	}
 	}
 
 
 	public int getDimension() {
 	public int getDimension() {
 		return dimension;
 		return dimension;
 	}
 	}
-	public int[] getSizes() {
+	public long[] getSizes() {
 		return sizes;
 		return sizes;
 	}
 	}
 	
 	
-	public void set(int dimension, int... sizes) {
+	public void set(int dimension, long... sizes) {
 		if (sizes==null || sizes.length!=3) {
 		if (sizes==null || sizes.length!=3) {
 			throw new IllegalArgumentException("sizes must be an array of length 3");
 			throw new IllegalArgumentException("sizes must be an array of length 3");
 		}
 		}

+ 36 - 8
jme3-examples/src/main/java/jme3test/opencl/HelloOpenCL.java

@@ -39,6 +39,7 @@ import com.jme3.opencl.*;
 import com.jme3.system.AppSettings;
 import com.jme3.system.AppSettings;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
 import java.util.logging.Level;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.logging.Logger;
 
 
@@ -137,15 +138,42 @@ public class HelloOpenCL extends SimpleApplication {
     }
     }
     
     
     private boolean testKernel(Context clContext, CommandQueue clQueue) {
     private boolean testKernel(Context clContext, CommandQueue clQueue) {
-        String include = "#define TYPE float\n";
-        Program program = clContext.createProgramFromSourceFilesWithInclude(assetManager, include, "jme3test/opencl/Blas.cl");
-        program.build();
-        Kernel[] kernels = program.createAllKernels();
-        for (Kernel k : kernels) {
-            System.out.println("available kernel: "+k.getName());
+        try {
+            //create fill code
+            String include = "#define TYPE float\n";
+            Program program = clContext.createProgramFromSourceFilesWithInclude(assetManager, include, "jme3test/opencl/Blas.cl");
+            program.build();
+            Kernel[] kernels = program.createAllKernels();
+            for (Kernel k : kernels) {
+                System.out.println("available kernel: "+k.getName());
+            }
+            Kernel kernel = program.createKernel("Fill");
+            System.out.println("number of args: "+kernel.getArgCount());
+
+            //fill buffer
+            int size = 256+128;
+            Buffer buffer = clContext.createBuffer(size*4);
+            float value = 5;
+            Event event = kernel.Run1(clQueue, new WorkSize(buffer.getSize() / 4), buffer, value);
+            event.waitForFinished();
+            
+            //check if filled
+            ByteBuffer buf = buffer.map(clQueue, MappingAccess.MAP_READ_ONLY);
+            FloatBuffer buff = buf.asFloatBuffer();
+            for (int i=0; i<size; ++i) {
+                float v = buff.get(i);
+                if (v != value) {
+                    System.err.println("Buffer filled with the wrong value at index "+i+": expected="+value+", actual="+v);
+                    buffer.unmap(clQueue, buf);
+                    return false;
+                }
+            }
+            buffer.unmap(clQueue, buf);
+
+        } catch (Exception ex) {
+            LOG.log(Level.SEVERE, "kernel test failed with:", ex);
+            return false;
         }
         }
-        Kernel kernel = program.createKernel("Fill");
-        System.out.println("number of args: "+kernel.getArgCount());
         return true;
         return true;
     }
     }
 }
 }

+ 90 - 15
jme3-lwjgl/src/main/java/com/jme3/opencl/lwjgl/LwjglKernel.java

@@ -35,8 +35,11 @@ import com.jme3.math.Quaternion;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector4f;
 import com.jme3.math.Vector4f;
 import com.jme3.opencl.*;
 import com.jme3.opencl.*;
-import java.nio.ByteBuffer;
+import com.jme3.opencl.Buffer;
+import java.nio.*;
+import org.lwjgl.PointerBuffer;
 import org.lwjgl.opencl.CL10;
 import org.lwjgl.opencl.CL10;
+import org.lwjgl.opencl.CLCommandQueue;
 import org.lwjgl.opencl.CLKernel;
 import org.lwjgl.opencl.CLKernel;
 
 
 /**
 /**
@@ -67,72 +70,144 @@ public class LwjglKernel extends Kernel {
 
 
     @Override
     @Override
     public void setArg(int index, LocalMemPerElement t) {
     public void setArg(int index, LocalMemPerElement t) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        int ret = CL10.clSetKernelArg (kernel, index, t.getSize() * workGroupSize.getSizes()[0] * workGroupSize.getSizes()[1] * workGroupSize.getSizes()[2]);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, LocalMem t) {
     public void setArg(int index, LocalMem t) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        int ret = CL10.clSetKernelArg (kernel, index, t.getSize());
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, Buffer t) {
     public void setArg(int index, Buffer t) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        int ret = CL10.clSetKernelArg(kernel, index, ((LwjglBuffer) t).getBuffer());
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, byte b) {
     public void setArg(int index, byte b) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        ByteBuffer buf = Utils.tempBuffers[0].b16;
+        buf.position(0);
+        buf.limit(1);
+        buf.put(0, b);
+        int ret = CL10.clSetKernelArg(kernel, index, buf);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, short s) {
     public void setArg(int index, short s) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        ShortBuffer buf = Utils.tempBuffers[0].b16s;
+        buf.position(0);
+        buf.limit(1);
+        buf.put(0, s);
+        int ret = CL10.clSetKernelArg(kernel, index, buf);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, int i) {
     public void setArg(int index, int i) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        IntBuffer buf = Utils.tempBuffers[0].b16i;
+        buf.position(0);
+        buf.limit(1);
+        buf.put(0, i);
+        int ret = CL10.clSetKernelArg(kernel, index, buf);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, long l) {
     public void setArg(int index, long l) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        LongBuffer buf = Utils.tempBuffers[0].b16l;
+        buf.position(0);
+        buf.limit(1);
+        buf.put(0, l);
+        int ret = CL10.clSetKernelArg(kernel, index, buf);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, float f) {
     public void setArg(int index, float f) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        FloatBuffer buf = Utils.tempBuffers[0].b16f;
+        buf.position(0);
+        buf.limit(1);
+        buf.put(0, f);
+        int ret = CL10.clSetKernelArg(kernel, index, buf);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, double d) {
     public void setArg(int index, double d) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        DoubleBuffer buf = Utils.tempBuffers[0].b16d;
+        buf.position(0);
+        buf.limit(1);
+        buf.put(0, d);
+        int ret = CL10.clSetKernelArg(kernel, index, buf);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, Vector2f v) {
     public void setArg(int index, Vector2f v) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        FloatBuffer buf = Utils.tempBuffers[0].b16f;
+        buf.position(0);
+        buf.limit(2);
+        buf.put(0, v.x);
+        buf.put(1, v.y);
+        int ret = CL10.clSetKernelArg(kernel, index, buf);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, Vector4f v) {
     public void setArg(int index, Vector4f v) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        FloatBuffer buf = Utils.tempBuffers[0].b16f;
+        buf.position(0);
+        buf.limit(4);
+        buf.put(0, v.x);
+        buf.put(1, v.y);
+        buf.put(2, v.z);
+        buf.put(3, v.w);
+        int ret = CL10.clSetKernelArg(kernel, index, buf);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, Quaternion q) {
     public void setArg(int index, Quaternion q) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        FloatBuffer buf = Utils.tempBuffers[0].b16f;
+        buf.position(0);
+        buf.limit(4);
+        buf.put(0, q.getX());
+        buf.put(1, q.getY());
+        buf.put(2, q.getZ());
+        buf.put(3, q.getW());
+        int ret = CL10.clSetKernelArg(kernel, index, buf);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public void setArg(int index, ByteBuffer buffer, long size) {
     public void setArg(int index, ByteBuffer buffer, long size) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        buffer.limit((int) (buffer.position() + size));
+        int ret = CL10.clSetKernelArg(kernel, index, buffer);
+        Utils.checkError(ret, "clSetKernelArg");
     }
     }
 
 
     @Override
     @Override
     public Event Run(CommandQueue queue) {
     public Event Run(CommandQueue queue) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        Utils.pointerBuffers[0].rewind();
+        Utils.pointerBuffers[1].rewind();
+        Utils.pointerBuffers[1].put(globalWorkSize.getSizes());
+        Utils.pointerBuffers[1].position(0);
+        PointerBuffer p2 = null;
+        if (workGroupSize.getSizes()[0] > 0) {
+            p2 = Utils.pointerBuffers[2].rewind();
+            p2.put(workGroupSize.getSizes());
+            p2.position(0);
+        }
+        CLCommandQueue q = ((LwjglCommandQueue) queue).getQueue();
+        int ret = CL10.clEnqueueNDRangeKernel(q, kernel,
+			globalWorkSize.getDimension(), null, Utils.pointerBuffers[1],
+			p2, null, Utils.pointerBuffers[0]);
+        Utils.checkError(ret, "clEnqueueNDRangeKernel");
+        return new LwjglEvent(q.getCLEvent(Utils.pointerBuffers[0].get(0)));
     }
     }
     
     
 }
 }