/// <summary> /// Enqueues a n-dimensional kernel to the command queue, which is executed asynchronously. /// </summary> /// <param name="kernel">The kernel that is to be enqueued.</param> /// <param name="workDimension">The dimensionality of the work.</param> /// <param name="workUnitsPerKernel">The number of work units per kernel.</param> /// <exception cref="OpenClException"> /// If the kernel could not be enqueued, then an <see cref="OpenClException" /> is /// thrown. /// </exception> public Task EnqueueNDRangeKernelAsync(Kernel kernel, int workDimension, int workUnitsPerKernel) { // Creates a new task completion source, which is used to signal when the command has completed TaskCompletionSource <bool> taskCompletionSource = new TaskCompletionSource <bool>(); // Enqueues the kernel Result result = EnqueuedCommandsNativeApi.EnqueueNDRangeKernel( Handle, kernel.Handle, ( uint )workDimension, null, new[] { new IntPtr(workUnitsPerKernel) }, null, 0, null, out IntPtr waitEventPointer ); // Checks if the kernel was enqueued successfully, if not, then an exception is thrown if (result != Result.Success) { throw new OpenClException("The kernel could not be enqueued.", result); } // Subscribes to the completed event of the wait event that was returned, when the command finishes, the task completion source is resolved AwaitableEvent awaitableEvent = new AwaitableEvent(waitEventPointer); awaitableEvent.OnCompleted += (sender, e) => { try { if (awaitableEvent.CommandExecutionStatus == CommandExecutionStatus.Error) { taskCompletionSource.TrySetException( new OpenClException( $"The command completed with the error code {awaitableEvent.CommandExecutionStatusCode}." ) ); } else { taskCompletionSource.TrySetResult(true); } } catch (Exception exception) { taskCompletionSource.TrySetException(exception); } finally { awaitableEvent.Dispose(); } }; return(taskCompletionSource.Task); }
public void EnqueueKernel(string kernelName, IntPtr[] globalWorkSize, IntPtr[] localWorkSize) { IntPtr ev = IntPtr.Zero; var errCodeRunKernel = EnqueuedCommandsNativeApi.EnqueueNDRangeKernel(commandQueue, kernels[kernelName], (uint)globalWorkSize.Length, null, globalWorkSize, localWorkSize, 0, null, out ev); ThrowOnError(errCodeRunKernel, String.Format("Failed to enqueue kernel {0}.", kernelName)); var errCodeEv = EventsNativeApi.ReleaseEvent(ev); ThrowOnError(errCodeEv, String.Format("Failed release event (EnqueueNDRangeKernel)")); }
/// <summary> /// Enqueues a n-dimensional kernel to the command queue. /// </summary> /// <param name="kernel">The kernel that is to be enqueued.</param> /// <param name="workDimension">The dimensionality of the work.</param> /// <param name="workUnitsPerKernel">The number of work units per kernel.</param> /// <exception cref="OpenClException">If the kernel could not be enqueued, then an <see cref="OpenClException"/> is thrown.</exception> public void EnqueueNDRangeKernel(Kernel kernel, int workDimension, int workUnitsPerKernel) { // Enqueues the kernel IntPtr waitEventPointer; Result result = EnqueuedCommandsNativeApi.EnqueueNDRangeKernel(this.Handle, kernel.Handle, (uint)workDimension, null, new IntPtr[] { new IntPtr(workUnitsPerKernel) }, null, 0, null, out waitEventPointer); // Checks if the kernel was enqueued successfully, if not, then an exception is thrown if (result != Result.Success) { throw new OpenClException("The kernel could not be enqueued.", result); } }
/// <summary> /// Enqueues a n-dimensional kernel to the command queue. /// </summary> /// <param name="kernel">The kernel that is to be enqueued.</param> /// <param name="workDimension">The dimensionality of the work.</param> /// <param name="workUnitsPerKernel">The number of work units per kernel.</param> /// <exception cref="OpenClException">If the kernel could not be enqueued, then an <see cref="OpenClException"/> is thrown.</exception> public void EnqueueNDRangeKernel(Kernel kernel, int workDimension, int globalSize, int localSize, int offset = 0) { // Enqueues the kernel IntPtr waitEventPointer = IntPtr.Zero; Result result = EnqueuedCommandsNativeApi.EnqueueNDRangeKernel(this.Handle, kernel.Handle, (uint)workDimension, new IntPtr[] { new IntPtr(offset) }, new IntPtr[] { new IntPtr(globalSize) }, new IntPtr[] { new IntPtr(localSize) }, 0, null, waitEventPointer); // Checks if the kernel was enqueued successfully, if not, then an exception is thrown if (result != Result.Success) { throw new OpenClException("The kernel could not be enqueued.", result); } }