#parse("main/Header.vm")
package com.nativelibs4java.opencl;
import static com.nativelibs4java.opencl.CLException.error;
import static com.nativelibs4java.opencl.JavaCL.CL;
import static com.nativelibs4java.opencl.library.IOpenCLLibrary.CL_FALSE;
import static com.nativelibs4java.opencl.library.IOpenCLLibrary.CL_QUEUE_PROPERTIES;
import static com.nativelibs4java.opencl.library.IOpenCLLibrary.CL_TRUE;
import java.util.EnumSet;
import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_command_queue;
import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_event;
import com.nativelibs4java.opencl.library.IOpenCLLibrary.cl_mem;
import org.bridj.*;
import static org.bridj.Pointer.*;
/**
* OpenCL command queue.<br>
* OpenCL objects such as memory, program and kernel objects are created using a context. <br>
* Operations on these objects are performed using a command-queue. <br>
* The command-queue can be used to queue a set of operations (referred to as commands) in order. <br>
* Having multiple command-queues allows applications to queue multiple independent commands without requiring synchronization. <br>
* Note that this should work as long as these objects are not being shared. <br>
* Sharing of objects across multiple command-queues will require the application to perform appropriate synchronization.<br>
* <br>
* A queue is bound to a single device.
* see {@link CLDevice#createQueue(com.nativelibs4java.opencl.CLContext, com.nativelibs4java.opencl.CLDevice.QueueProperties[]) }
* see {@link CLDevice#createOutOfOrderQueue(com.nativelibs4java.opencl.CLContext) }
* see {@link CLDevice#createProfilingQueue(com.nativelibs4java.opencl.CLContext) }
* see {@link CLContext#createDefaultQueue(com.nativelibs4java.opencl.CLDevice.QueueProperties[]) }
* see {@link CLContext#createDefaultOutOfOrderQueue() }
* see {@link CLContext#createDefaultProfilingQueue() }
* @author Olivier Chafik
*
*/
public class CLQueue extends CLAbstractEntity {
#declareInfosGetter("infos", "CL.clGetCommandQueueInfo")
final CLContext context;
final CLDevice device;
CLQueue(CLContext context, long entity, CLDevice device) {
super(entity);
this.context = context;
this.device = device;
}
public CLContext getContext() {
return context;
}
public CLDevice getDevice() {
return device;
}
volatile Boolean outOfOrder;
public synchronized boolean isOutOfOrder() {
if (outOfOrder == null)
outOfOrder = getProperties().contains(CLDevice.QueueProperties.OutOfOrderExecModeEnable);
return outOfOrder;
}
@InfoName("CL_QUEUE_PROPERTIES")
public EnumSet<CLDevice.QueueProperties> getProperties() {
return CLDevice.QueueProperties.getEnumSet(infos.getIntOrLong(getEntity(), CL_QUEUE_PROPERTIES));
}
@SuppressWarnings("deprecation")
public void setProperty(CLDevice.QueueProperties property, boolean enabled) {
context.getPlatform().requireMinVersionValue("clSetCommandQueueProperty", 1.0, 1.1);
error(CL.clSetCommandQueueProperty(getEntity(), property.value(), enabled ? CL_TRUE : CL_FALSE, 0));
}
@Override
protected void clear() {
error(CL.clReleaseCommandQueue(getEntity()));
}
/**
#documentCallsFunction("clFinish")
* Blocks until all previously queued OpenCL commands in this queue are issued to the associated device and have completed. <br>
* finish() does not return until all queued commands in this queue have been processed and completed. <br>
* finish() is also a synchronization point.
*/
public void finish() {
error(CL.clFinish(getEntity()));
}
/**
#documentCallsFunction("clFlush")
* Issues all previously queued OpenCL commands in this queue to the device associated with this queue. <br>
* flush() only guarantees that all queued commands in this queue get issued to the appropriate device. <br>
* There is no guarantee that they will be complete after flush() returns.
*/
public void flush() {
error(CL.clFlush(getEntity()));
}
/**
#documentCallsFunction("clEnqueueWaitForEvents")
* Enqueues a wait for a specific event or a list of events to complete before any future commands queued in the this queue are executed.
*/
public void enqueueWaitForEvents(CLEvent... eventsToWaitFor) {
context.getPlatform().requireMinVersionValue("clEnqueueWaitForEvents", 1.1, 1.2);
#declareReusablePtrs()
#declareEventsIn()
if (eventsIn == null)
return;
error(CL.clEnqueueWaitForEvents(getEntity(), #eventsInArgsRaw()));
}
/**
#documentCallsFunction("clEnqueueMigrateMemObjects")
* Enqueues a command to indicate which device a set of memory objects should be associated with.
*/
public CLEvent enqueueMigrateMemObjects(CLMem[] memObjects, EnumSet<CLMem.Migration> flags, CLEvent... eventsToWaitFor) {
context.getPlatform().requireMinVersionValue("clEnqueueMigrateMemObjects", 1.2);
#declareReusablePtrsAndEventsInOut()
int[] n = ptrs.int1Array;
Pointer<SizeT> pMems = pointerToEntities(memObjects, n);
error(CL.clEnqueueMigrateMemObjects(
getEntity(),
n[0],
getPeer(pMems),
CLMem.Migration.getValue(flags),
#eventsInOutArgsRaw()
));
#returnEventOut("this")
}
//
public interface NativeKernel {
void execute(Pointer[] bufferPointers);
}
private static Pointer<SizeT> pointerToEntities(CLAbstractEntity[] entities, int[] n) {
int nn = 0;
Pointer<SizeT> pEntities = allocateSizeTs(entities.length);
for (CLAbstractEntity entity : entities) {
if (entity != null) {
pEntities.setSizeTAtIndex(nn++, entity.getEntity());
}
}
n[0] = nn;
return pEntities;
}
/**
#documentCallsFunction("clEnqueueNativeKernel")
* Enqueues a command to execute a Java callback with direct access to buffer memory.
*/
/*
public CLEvent enqueueNativeKernel(NativeKernel kernel, CLMem[] buffers, CLEvent... eventsToWaitFor) {
// TODO check 1.1 or 1.2?
context.getPlatform().requireMinVersionValue("clEnqueueNativeKernel", 1.2);
#declareReusablePtrsAndEventsInOut()
int[] n = ptrs.int1Array;
Pointer<SizeT> pMems = pointerToEntities(buffers, n);
error(CL.clEnqueueNativeKernel(
getEntity(),
n[0],
getPeer(pMems),
CLMem.Migration.getValue(flags),
#eventsInOutArgsRaw()
));
#returnEventOut("this")
}
*/
/**
#documentCallsFunction("clEnqueueBarrierWithWaitList")
* Enqueue a barrier operation.<br>
* The enqueueBarrier() command ensures that all queued commands in command_queue have finished execution before the next batch of commands can begin execution. <br>
* enqueueBarrier() is a synchronization point.
#documentEventsToWaitForAndReturn()
*/
public CLEvent enqueueBarrier(CLEvent... eventsToWaitFor) {
if (context.getPlatform().getVersionValue() >= 1.2 ||
eventsToWaitFor != null && eventsToWaitFor.length > 0)
{
context.getPlatform().requireMinVersionValue("clEnqueueBarrierWithWaitList", 1.2);
#declareReusablePtrsAndEventsInOut()
error(CL.clEnqueueBarrierWithWaitList(
getEntity(),
#eventsInOutArgsRaw()
));
#returnEventOut("this")
} else {
context.getPlatform().requireMinVersionValue("clEnqueueBarrier", 1.1, 1.2);
error(CL.clEnqueueBarrier(getEntity()));
return null;
}
}
/**
#documentCallsFunction("clEnqueueMarkerWithWaitList")
* Enqueue a marker command to command_queue. <br>
* The marker command returns an event which can be used by to queue a wait on this marker event i.e. wait for all commands queued before the marker command to complete.
#documentEventsToWaitForAndReturn()
*/
@Deprecated
public CLEvent enqueueMarker(CLEvent... eventsToWaitFor) {
if (context.getPlatform().getVersionValue() >= 1.2 ||
eventsToWaitFor != null && eventsToWaitFor.length > 0)
{
context.getPlatform().requireMinVersionValue("clEnqueueMarkerWithWaitList", 1.2);
#declareReusablePtrsAndEventsInOut()
error(CL.clEnqueueMarkerWithWaitList(
getEntity(),
#eventsInOutArgsRaw()
));
#returnEventOut("this")
} else {
context.getPlatform().requireMinVersionValue("clEnqueueMarker", 1.1, 1.2);
#declareReusablePtrs()
Pointer<cl_event> eventOut = ptrs.event_out;
error(CL.clEnqueueMarker(getEntity(), getPeer(eventOut)));
#returnEventOut("this")
}
}
/**
#documentCallsFunction("clEnqueueAcquireGLObjects")
* Used to acquire OpenCL memory objects that have been created from OpenGL objects. <br>
* These objects need to be acquired before they can be used by any OpenCL commands queued to a command-queue. <br>
* The OpenGL objects are acquired by the OpenCL context associated with this queue and can therefore be used by all command-queues associated with the OpenCL context.
* @param objects CL memory objects that correspond to GL objects.
#documentEventsToWaitForAndReturn()
*/
public CLEvent enqueueAcquireGLObjects(CLMem[] objects, CLEvent... eventsToWaitFor) {
#declareReusablePtrsAndEventsInOut()
Pointer<SizeT> mems = allocateSizeTs(objects.length);
for (int i = 0; i < objects.length; i++) {
mems.setSizeTAtIndex(i, objects[i].getEntity());
}
error(CL.clEnqueueAcquireGLObjects(
getEntity(),
objects.length,
getPeer(mems),
#eventsInOutArgsRaw()
));
#returnEventOut("this")
}
/**
#documentCallsFunction("clEnqueueReleaseGLObjects")
* Used to release OpenCL memory objects that have been created from OpenGL objects. <br>
* These objects need to be released before they can be used by OpenGL. <br>
* The OpenGL objects are released by the OpenCL context associated with this queue.
* @param objects CL memory objects that correpond to GL objects.
#documentEventsToWaitForAndReturn()
*/
public CLEvent enqueueReleaseGLObjects(CLMem[] objects, CLEvent... eventsToWaitFor) {
#declareReusablePtrsAndEventsInOut()
Pointer<?> mems = getEntities(objects, (Pointer)allocateSizeTs(objects.length));
error(CL.clEnqueueReleaseGLObjects(
getEntity(),
objects.length,
getPeer(mems),
#eventsInOutArgsRaw()
));
#returnEventOut("this")
}
}