Пример #1
0
        /// <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);
        }
Пример #2
0
        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)"));
        }
Пример #3
0
        /// <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);
            }
        }
Пример #4
0
        /// <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);
            }
        }