/// <summary>
        /// Performs a reduction using a reduction logic.
        /// </summary>
        /// <typeparam name="T">The underlying type of the reduction.</typeparam>
        /// <typeparam name="TShuffleDown">The type of the shuffle logic.</typeparam>
        /// <typeparam name="TReduction">The type of the reduction logic.</typeparam>
        /// <param name="accelerator">The accelerator.</param>
        /// <param name="stream">The accelerator stream.</param>
        /// <param name="input">The input elements to reduce.</param>
        /// <param name="shuffleDown">The shuffle logic.</param>
        /// <param name="reduction">The reduction logic.</param>
        /// <remarks>Uses the internal cache to realize a temporary output buffer.</remarks>
        /// <returns>The reduced value.</returns>
        public static T Reduce <T, TShuffleDown, TReduction>(
            this Accelerator accelerator,
            AcceleratorStream stream,
            ArrayView <T> input,
            TShuffleDown shuffleDown,
            TReduction reduction)
            where T : struct
            where TShuffleDown : struct, IShuffleDown <T>
            where TReduction : struct, IReduction <T>
        {
            if (!input.IsValid)
            {
                throw new ArgumentNullException(nameof(input));
            }
            if (input.Length < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(input));
            }
            var tempStorageSize = accelerator.ComputeReductionTempStorageSize(input.Length);
            var storage         = accelerator.MemoryCache.Allocate <T>(tempStorageSize + 1);
            var output          = storage.GetSubView(0, 1);
            var temp            = storage.GetSubView(1);

            accelerator.Reduce(
                stream,
                input,
                output,
                temp,
                shuffleDown,
                reduction);
            stream.Synchronize();
            accelerator.MemoryCache.CopyTo(out T result, 0);
            return(result);
        }
예제 #2
0
 /// <summary>
 /// Waits for <see cref="CopyToGPU"/> to finish
 /// </summary>
 /// <remarks>
 /// This function is useless until Multidimensional ExchangeBuffers release
 /// </remarks>
 public void WaitForCopy()
 {
     if (stream != null)
     {
         stream.Synchronize();
     }
 }
예제 #3
0
        /// <summary>
        /// Access a specific slice of either a column 'c' or row 'r' of this vector
        /// </summary>
        /// <param name="gpu"></param>
        /// <param name="row_col_index"></param>
        /// <param name="row_col"></param>
        /// <returns></returns>
        public Vector _AccessSlice(int row_col_index, char row_col)
        {
            if (this.Columns == 1)
            {
                throw new Exception("Input Vector cannot be 1D");
            }

            int[] ChangeSelectLength;
            int   OutPutVectorLength;

            switch (row_col)
            {
            case 'r':
                //ChangeSelectLength = new int[5] { 0, 1, row_col_index, 0, vector.Columns };
                //OutPutVectorLength = vector.Columns;
                return(this._AccessRow(this, row_col_index));

            case 'c':
                ChangeSelectLength = new int[5] {
                    1, 0, 0, row_col_index, this.Columns
                };
                OutPutVectorLength = this.Value.Length / this.Columns;
                break;

            default:
                throw new Exception("Invalid slice char selector, choose 'r' for row or 'c' for column");
            }

            //this is bad and I should feel bad
            Accelerator       gpu    = this.gpu.accelerator;
            AcceleratorStream Stream = gpu.CreateStream();

            var kernelWithStream = gpu.LoadAutoGroupedKernel <Index1, ArrayView <float>, ArrayView <float>, ArrayView <int> >(AccessSliceKernal);

            var buffer  = gpu.Allocate <float>(OutPutVectorLength);
            var buffer2 = gpu.Allocate <float>(this.Value.Length);
            var buffer3 = gpu.Allocate <int>(5);

            buffer.MemSetToZero(Stream);
            buffer2.MemSetToZero(Stream);
            buffer3.MemSetToZero(Stream);

            buffer2.CopyFrom(Stream, this.Value, 0, 0, this.Value.Length);
            buffer3.CopyFrom(Stream, ChangeSelectLength, 0, 0, ChangeSelectLength.Length);

            kernelWithStream(Stream, OutPutVectorLength, buffer.View, buffer2.View, buffer3.View);

            Stream.Synchronize();

            float[] Output = buffer.GetAsArray(Stream);

            buffer.Dispose();
            buffer2.Dispose();
            buffer3.Dispose();

            Stream.Dispose();

            return(new Vector(this.gpu, Output));
        }
예제 #4
0
 /// <inheritdoc/>
 protected internal override unsafe void MemSetInternal(
     AcceleratorStream stream,
     byte value,
     long offsetInBytes,
     long lengthInBytes)
 {
     stream.Synchronize();
     ref byte targetAddress = ref Unsafe.AsRef <byte>(NativePtr.ToPointer());
예제 #5
0
        /// <summary>
        /// Performs a reduction using a reduction logic.
        /// </summary>
        /// <typeparam name="T">The underlying type of the reduction.</typeparam>
        /// <typeparam name="TReduction">The type of the reduction logic.</typeparam>
        /// <param name="accelerator">The accelerator.</param>
        /// <param name="stream">The accelerator stream.</param>
        /// <param name="input">The input elements to reduce.</param>
        /// <remarks>
        /// Uses the internal cache to realize a temporary output buffer.
        /// </remarks>
        /// <returns>The reduced value.</returns>
        public static T Reduce <T, TReduction>(
            this Accelerator accelerator,
            AcceleratorStream stream,
            ArrayView <T> input)
            where T : unmanaged
            where TReduction : struct, IScanReduceOperation <T>
        {
            var output = accelerator.MemoryCache.Allocate <T>(1);

            accelerator.Reduce <T, TReduction>(stream, input, output);
            stream.Synchronize();
            accelerator.MemoryCache.CopyTo(stream, out T result, 0);
            return(result);
        }
 /// <summary>
 /// Removes consecutive duplicate elements in a supplied input view.
 /// </summary>
 /// <typeparam name="T">The input view element type.</typeparam>
 /// <typeparam name="TComparisonOperation">The comparison operation.</typeparam>
 /// <param name="accelerator">The accelerator.</param>
 /// <param name="stream">The accelerator stream.</param>
 /// <param name="input">The input view.</param>
 /// <returns>The new/valid length of the input view.</returns>
 public static long Unique <T, TComparisonOperation>(
     this Accelerator accelerator,
     AcceleratorStream stream,
     ArrayView <T> input)
     where T : unmanaged
     where TComparisonOperation : struct, IComparisonOperation <T>
 {
     using var output = accelerator.Allocate <long>(1);
     using var temp   = accelerator.Allocate <int>(
               accelerator.ComputeUniqueTempStorageSize <T>(input.Length));
     accelerator.CreateUnique <T, TComparisonOperation>()(
         stream,
         input,
         output,
         temp);
     stream.Synchronize();
     output.CopyTo(stream, out long result, 0);
     return(result);
 }
        /// <summary>
        /// Performs a reduction using an atomic reduction logic.
        /// </summary>
        /// <typeparam name="T">The underlying type of the reduction.</typeparam>
        /// <typeparam name="TShuffleDown">The type of the shuffle logic.</typeparam>
        /// <typeparam name="TReduction">The type of the reduction logic.</typeparam>
        /// <param name="accelerator">The accelerator.</param>
        /// <param name="stream">The accelerator stream.</param>
        /// <param name="input">The input elements to reduce.</param>
        /// <param name="shuffleDown">The shuffle logic.</param>
        /// <param name="reduction">The reduction logic.</param>
        /// <remarks>Uses the internal cache to realize a temporary output buffer.</remarks>
        /// <returns>The reduced value.</returns>
        public static T AtomicReduce <T, TShuffleDown, TReduction>(
            this Accelerator accelerator,
            AcceleratorStream stream,
            ArrayView <T> input,
            TShuffleDown shuffleDown,
            TReduction reduction)
            where T : struct
            where TShuffleDown : struct, IShuffleDown <T>
            where TReduction : struct, IAtomicReduction <T>
        {
            var output = accelerator.MemoryCache.Allocate <T>(1);

            accelerator.AtomicReduce(
                stream,
                input,
                output,
                shuffleDown,
                reduction);
            stream.Synchronize();
            accelerator.MemoryCache.CopyTo(out T result, 0);
            return(result);
        }
예제 #8
0
 /// <summary cref="MemoryBuffer.MemSetToZero(AcceleratorStream)"/>
 public unsafe override void MemSetToZero(AcceleratorStream stream)
 {
     stream.Synchronize();
     Unsafe.InitBlock(NativePtr.ToPointer(), 0, (uint)LengthInBytes);
 }
예제 #9
0
 /// <summary cref="MemoryBuffer.MemSetToZero(AcceleratorStream)"/>
 public unsafe override void MemSetToZero(AcceleratorStream stream)
 {
     stream.Synchronize();
     ref byte targetAddress = ref Unsafe.AsRef <byte>(NativePtr.ToPointer());