コード例 #1
0
        /// <summary>
        /// Reads the specified memory object associated with this command queue.
        /// </summary>
        /// <param name="memoryObject">The memory object that is to be read.</param>
        /// <param name="outputLength">The number of array elements that are to be filled.</param>
        /// <typeparam name="T">The type of the array that is to be returned.</typeparam>
        /// <returns>Returns the value of the memory object.</param>
        public unsafe void EnqueueReadBuffer <T>(MemoryObject memoryObject, int outputLength, ref T[] output)
        {
            switch (output)
            {
            case uint[] uintArray:
                unsafe
                {
                    fixed(uint *uintPtr = uintArray)
                    {
                        Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)(sizeof(uint) * outputLength)), (IntPtr)((void *)uintPtr), 0, null, out IntPtr zero);

                        if (result != Result.Success)
                        {
                            throw new OpenClException("The memory object could not be read.", result);
                        }
                    }

                    break;
                }

            case int[] intArray:
                unsafe
                {
                    fixed(int *intPtr = intArray)
                    {
                        Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)(sizeof(int) * outputLength)), (IntPtr)((void *)intPtr), 0, null, out IntPtr zero);

                        if (result != Result.Success)
                        {
                            throw new OpenClException("The memory object could not be read.", result);
                        }
                    }

                    break;
                }

            case byte[] byteArray:
                unsafe
                {
                    fixed(byte *bytePtr = byteArray)
                    {
                        Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)(outputLength)), (IntPtr)((void *)bytePtr), 0, null, out IntPtr zero);

                        if (result != Result.Success)
                        {
                            throw new OpenClException("The memory object could not be read.", result);
                        }
                    }

                    break;
                }

            case sbyte[] sbyteArray:
                unsafe
                {
                    fixed(sbyte *sbytePtr = sbyteArray)
                    {
                        Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)(outputLength)), (IntPtr)((void *)sbytePtr), 0, null, out IntPtr zero);

                        if (result != Result.Success)
                        {
                            throw new OpenClException("The memory object could not be read.", result);
                        }
                    }

                    break;
                }

            case ulong[] ulongArray:
                unsafe
                {
                    fixed(ulong *ulongPtr = ulongArray)
                    {
                        Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)(sizeof(ulong) * outputLength)), (IntPtr)((void *)ulongPtr), 0, null, out IntPtr zero);

                        if (result != Result.Success)
                        {
                            throw new OpenClException("The memory object could not be read.", result);
                        }
                    }

                    break;
                }

            case long[] longArray:
                unsafe
                {
                    fixed(long *longPtr = longArray)
                    {
                        Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)(sizeof(long) * outputLength)), (IntPtr)((void *)longPtr), 0, null, out IntPtr zero);

                        if (result != Result.Success)
                        {
                            throw new OpenClException("The memory object could not be read.", result);
                        }
                    }

                    break;
                }

            default:
                throw new NotSupportedException("Non-blittable types are not supported.");
            }
        }
コード例 #2
0
ファイル: CommandQueue.cs プロジェクト: ByteChkR/Byt3
        /// <summary>
        /// Reads the specified memory object associated with this command queue asynchronously.
        /// </summary>
        /// <param name="memoryObject">The memory object that is to be read.</param>
        /// <param name="outputSize">The number of array elements that are to be returned.</param>
        /// <typeparam name="T">The type of the array that is to be returned.</typeparam>
        /// <returns>Returns the value of the memory object.</param>
        public Task <T[]> EnqueueReadBufferAsync <T>(MemoryObject memoryObject, int outputSize) where T : struct
        {
            // Creates a new task completion source, which is used to signal when the command has completed
            TaskCompletionSource <T[]> taskCompletionSource = new TaskCompletionSource <T[]>();

            // Allocates enough memory for the result value
            IntPtr resultValuePointer = IntPtr.Zero;
            int    size = Marshal.SizeOf <T>() * outputSize;

            resultValuePointer = Marshal.AllocHGlobal(size);

            // Reads the memory object, by enqueuing the read operation to the command queue
            Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(Handle, memoryObject.Handle, 1, UIntPtr.Zero,
                                                                        new UIntPtr((uint)size), resultValuePointer, 0, null, out IntPtr waitEventPointer);

            // Checks if the read operation was queued successfuly, if not, an exception is thrown
            if (result != Result.Success)
            {
                throw new OpenClException("The memory object could not be read.", 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
                {
                    // Checks if the command was executed successfully, if not, then an exception is thrown
                    if (awaitableEvent.CommandExecutionStatus == CommandExecutionStatus.Error)
                    {
                        taskCompletionSource.TrySetException(new OpenClException(
                                                                 $"The command completed with the error code {awaitableEvent.CommandExecutionStatusCode}."));
                        return;
                    }

                    // Goes through the result and converts the content of the result to an array
                    T[] resultValue = new T[outputSize];
                    for (int i = 0; i < outputSize; i++)
                    {
                        resultValue[i] =
                            Marshal.PtrToStructure <T>(IntPtr.Add(resultValuePointer, i * Marshal.SizeOf <T>()));
                    }

                    // Sets the result
                    taskCompletionSource.TrySetResult(resultValue);
                }
                catch (Exception exception)
                {
                    taskCompletionSource.TrySetException(exception);
                }
                finally
                {
                    // Finally the allocated memory has to be freed and the allocated resources are disposed of
                    if (resultValuePointer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(resultValuePointer);
                    }

                    awaitableEvent.Dispose();
                }
            };

            // Returns the task completion source, which resolves when the command has finished
            return(taskCompletionSource.Task);
        }
コード例 #3
0
        /// <summary>
        /// Reads the specified memory object associated with this command queue.
        /// </summary>
        /// <param name="memoryObject">The memory object that is to be read.</param>
        /// <param name="outputLength">The number of array elements that are to be returned.</param>
        /// <typeparam name="T">The type of the array that is to be returned.</typeparam>
        /// <returns>Returns the value of the memory object.</param>
        public T[] EnqueueReadBuffer <T>(MemoryObject memoryObject, int outputLength) where T : struct
        {
            T[] resultValue = new T[outputLength];
#if UNSAFE
            switch (resultValue)
            {
            case int[] intArray:
                unsafe
                {
                    fixed(int *intPtr = intArray)
                    {
                        Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)(sizeof(int) * outputLength)), (IntPtr)((void *)intPtr), 0, null, out IntPtr zero);

                        if (result != Result.Success)
                        {
                            throw new OpenClException("The memory object could not be read.", result);
                        }
                    }

                    return(resultValue);
                }

            case uint[] uintArray:
                unsafe
                {
                    fixed(uint *uintPtr = uintArray)
                    {
                        Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)(sizeof(uint) * outputLength)), (IntPtr)((void *)uintPtr), 0, null, out IntPtr zero);

                        if (result != Result.Success)
                        {
                            throw new OpenClException("The memory object could not be read.", result);
                        }
                    }

                    return(resultValue);
                }

            default:
                // Tries to read the memory object
                IntPtr resultValuePointer = IntPtr.Zero;
                try
                {
                    // Allocates enough memory for the result value
                    int size = Marshal.SizeOf <T>() * outputLength;
                    resultValuePointer = Marshal.AllocHGlobal(size);

                    // Reads the memory object, by enqueuing the read operation to the command queue
                    IntPtr waitEventPointer;
                    Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)size), resultValuePointer, 0, null, out waitEventPointer);

                    // Checks if the read operation was queued successfuly, if not, an exception is thrown
                    if (result != Result.Success)
                    {
                        throw new OpenClException("The memory object could not be read.", result);
                    }

                    // Goes through the result and converts the content of the result to an array
                    for (int i = 0; i < outputLength; i++)
                    {
                        resultValue[i] = Marshal.PtrToStructure <T>(IntPtr.Add(resultValuePointer, i * Marshal.SizeOf <T>()));
                    }

                    // Returns the content of the memory object
                    return(resultValue);
                }
                finally
                {
                    // Finally the allocated memory has to be freed
                    if (resultValuePointer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(resultValuePointer);
                    }
                }
            }
#else
            // Tries to read the memory object
            IntPtr resultValuePointer = IntPtr.Zero;
            try
            {
                // Allocates enough memory for the result value
                int size = Marshal.SizeOf <T>() * outputLength;
                resultValuePointer = Marshal.AllocHGlobal(size);

                // Reads the memory object, by enqueuing the read operation to the command queue
                IntPtr waitEventPointer;
                Result result = EnqueuedCommandsNativeApi.EnqueueReadBuffer(this.Handle, memoryObject.Handle, 1, UIntPtr.Zero, new UIntPtr((uint)size), resultValuePointer, 0, null, out waitEventPointer);

                // Checks if the read operation was queued successfuly, if not, an exception is thrown
                if (result != Result.Success)
                {
                    throw new OpenClException("The memory object could not be read.", result);
                }

                // Goes through the result and converts the content of the result to an array
                for (int i = 0; i < outputLength; i++)
                {
                    resultValue[i] = Marshal.PtrToStructure <T>(IntPtr.Add(resultValuePointer, i * Marshal.SizeOf <T>()));
                }

                // Returns the content of the memory object
                return(resultValue);
            }
            finally
            {
                // Finally the allocated memory has to be freed
                if (resultValuePointer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(resultValuePointer);
                }
            }
#endif
        }