/// <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); }
/// <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(); } }
/// <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)); }
/// <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());
/// <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); }
/// <summary cref="MemoryBuffer.MemSetToZero(AcceleratorStream)"/> public unsafe override void MemSetToZero(AcceleratorStream stream) { stream.Synchronize(); Unsafe.InitBlock(NativePtr.ToPointer(), 0, (uint)LengthInBytes); }
/// <summary cref="MemoryBuffer.MemSetToZero(AcceleratorStream)"/> public unsafe override void MemSetToZero(AcceleratorStream stream) { stream.Synchronize(); ref byte targetAddress = ref Unsafe.AsRef <byte>(NativePtr.ToPointer());