/// <summary> /// Creates a new instance of a reduction handler. /// </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> /// <returns>The created reduction handler.</returns> public static Reduction <T> CreateReduction <T, TReduction>( this Accelerator accelerator) where T : unmanaged where TReduction : struct, IScanReduceOperation <T> { var initializer = accelerator.CreateInitializer <T>(); var kernel = accelerator.LoadKernel <ArrayView <T>, ArrayView <T> >( ReductionKernel <T, TReduction>); return((stream, input, output) => { if (!input.IsValid) { throw new ArgumentNullException(nameof(input)); } if (input.Length < 1) { throw new ArgumentOutOfRangeException(nameof(input)); } if (!output.IsValid) { throw new ArgumentNullException(nameof(output)); } if (output.Length < 1) { throw new ArgumentOutOfRangeException(nameof(output)); } var dimension = ComputeReductionDimension(accelerator, input.Length); TReduction reduction = default; initializer(stream, output, reduction.Identity); kernel(stream, dimension, input, output); }); }
/// <summary> /// Creates a kernel to remove consecutive duplicate elements in a given view. /// </summary> /// <typeparam name="T">The input view element type.</typeparam> /// <typeparam name="TComparisonOperation">The comparison operation.</typeparam> /// <param name="accelerator">The accelerator.</param> /// <returns>The created unique handler.</returns> public static Unique <T> CreateUnique <T, TComparisonOperation>( this Accelerator accelerator) where T : unmanaged where TComparisonOperation : struct, IComparisonOperation <T> { var initializer = accelerator.CreateInitializer <int, Stride1D.Dense>(); var kernel = accelerator.LoadKernel < ArrayView <T>, ArrayView <long>, SequentialGroupExecutor, SpecializedValue <int>, Index1D>( UniqueKernel <T, TComparisonOperation>); return((stream, input, output, temp) => { if (!input.IsValid) { throw new ArgumentNullException(nameof(input)); } if (!output.IsValid) { throw new ArgumentNullException(nameof(output)); } if (!temp.IsValid) { throw new ArgumentNullException(nameof(temp)); } if (output.Length < 1) { throw new ArgumentOutOfRangeException(nameof(output)); } if (temp.Length < accelerator.ComputeUniqueTempStorageSize <T>(input.Length)) { throw new ArgumentOutOfRangeException(nameof(temp)); } if (input.Length > int.MaxValue) { throw new NotSupportedException( ErrorMessages.NotSupportedArrayView64); } var viewManager = new TempViewManager(temp, nameof(temp)); var executorView = viewManager.Allocate <int>(); initializer(stream, temp.SubView(0, viewManager.NumInts), default); var(gridDim, groupDim) = accelerator.ComputeGridStrideLoopExtent( input.IntLength, out int numIterationsPerGroup); kernel( stream, (gridDim, groupDim), input, output, new SequentialGroupExecutor(executorView), new SpecializedValue <int>(groupDim * numIterationsPerGroup), numIterationsPerGroup); }); }
/// <summary> /// Creates a new instance of an atomic reduction handler. /// </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> /// <returns>The created reduction handler.</returns> public static AtomicReduction <T, TShuffleDown, TReduction> CreateAtomicReduction <T, TShuffleDown, TReduction>( this Accelerator accelerator) where T : struct where TShuffleDown : struct, IShuffleDown <T> where TReduction : struct, IAtomicReduction <T> { var kernel = accelerator.LoadKernel <Action <AcceleratorStream, GroupedIndex, ArrayView <T>, ArrayView <T>, TShuffleDown, TReduction> >( ReductionImpl <T, TShuffleDown, TReduction, AtomicReductionFinalizer <T, TReduction> > .KernelMethod); var initializer = accelerator.CreateInitializer <T>(); return((stream, input, output, shuffleDown, reduction) => { if (!input.IsValid) { throw new ArgumentNullException(nameof(input)); } if (input.Length < 1) { throw new ArgumentOutOfRangeException(nameof(input)); } if (!output.IsValid) { throw new ArgumentNullException(nameof(output)); } if (output.Length < 1) { throw new ArgumentOutOfRangeException(nameof(output)); } var dimension = ComputeReductionDimension(accelerator, input.Length); initializer(stream, output, reduction.NeutralElement); kernel(stream, dimension, input, output, shuffleDown, reduction); }); }
/// <summary> /// Creates a new radix sort operation. /// </summary> /// <typeparam name="T">The underlying type of the sort operation.</typeparam> /// <typeparam name="TRadixSortMapper">The type of the radix sort mapper.</typeparam> /// <param name="accelerator">The accelerator.</param> /// <param name="kind">The radix sort kind.</param> /// <returns>The created radix sort handler.</returns> public static RadixSort <T, TRadixSortMapper> CreateRadixSort <T, TRadixSortMapper>( this Accelerator accelerator, RadixSortKind kind) where T : struct where TRadixSortMapper : struct, IRadixSortMapper <T> { var ascending = kind == RadixSortKind.Ascending; var initializer = accelerator.CreateInitializer <Index>(); var radixSort = accelerator.LoadAutoGroupedKernel < Action <AcceleratorStream, Index, ArrayView <T>, ArrayView <T>, TRadixSortMapper, ArrayView <Index>, ArrayView <Index>, int, int> >( RadixSortImpl <T, TRadixSortMapper> .KernelMethod, out int groupSize, out int minGridSize); var minDataSize = groupSize * minGridSize; return((stream, input, output, counterView, mapper) => { if (!input.IsValid) { throw new ArgumentNullException(nameof(input)); } if (!output.IsValid) { throw new ArgumentNullException(nameof(output)); } if (!counterView.IsValid) { throw new ArgumentNullException(nameof(counterView)); } var tempSize = ComputeRadixSortTempStorageSize(accelerator, input.Length); if (counterView.Length < tempSize) { throw new ArgumentOutOfRangeException(nameof(counterView)); } var dimension = Math.Min(minDataSize, input.Length); var leftCounterView = counterView.GetSubView(0, 1); var rightCounterView = counterView.GetSubView(1, 1); int leftTrue = ascending ? 0 : 1; int rightTrue = ascending ? 1 : 0; var endBitIdx = mapper.NumRadixBits; if ((endBitIdx & 1) != 0) { throw new ArgumentOutOfRangeException(nameof(mapper)); } for (int bitIdx = 0; bitIdx < endBitIdx; ++bitIdx) { initializer(stream, counterView, Index.Zero); // Sort to buckets radixSort(stream, dimension, input, output, mapper, rightCounterView, leftCounterView, bitIdx, leftTrue); radixSort(stream, dimension, input, output, mapper, leftCounterView, rightCounterView, bitIdx, rightTrue); Utilities.Swap(ref input, ref output); } }); }
private int runILGPUTest(int items, TimeSpan duration, Accelerator acc, bool copyBack) { int count = 0; var init = acc.CreateInitializer <Vector2>(); using (var buffer1 = acc.Allocate <Vector2>(items)) { init(acc.DefaultStream, buffer1, Vector2.One); using (var buffer2 = acc.Allocate <Vector2>(items)) { init(acc.DefaultStream, buffer2, Vector2.One); var run = acc.LoadAutoGroupedStreamKernel <ILGPU.Index, ArrayView <Vector2>, ArrayView <Vector2> >(ilgpu_test); ILGPU.Index idx = new ILGPU.Index(items); Stopwatch sb = new Stopwatch(); sb.Start(); while (sb.Elapsed < duration) { run(idx, buffer1, buffer2); acc.Synchronize(); count++; if (copyBack) { buffer1.GetAsArray(); } count++; } } } return(count); }
/// <summary> /// Performs an initialization on the given view. /// </summary> /// <typeparam name="T">The element type.</typeparam> /// <param name="accelerator">The accelerator.</param> /// <param name="stream">The accelerator stream.</param> /// <param name="view">The element view.</param> /// <param name="value">The target value.</param> public static void Initialize <T>( this Accelerator accelerator, AcceleratorStream stream, ArrayView <T> view, T value) where T : unmanaged => accelerator.CreateInitializer <T, Stride1D.Dense>()( stream, view, value);
/// <summary> /// Performs an initialization on the given view. /// </summary> /// <typeparam name="T">The element type.</typeparam> /// <typeparam name="TStride">The 1D stride of the target view.</typeparam> /// <param name="accelerator">The accelerator.</param> /// <param name="stream">The accelerator stream.</param> /// <param name="view">The element view.</param> /// <param name="value">The target value.</param> public static void Initialize <T, TStride>( this Accelerator accelerator, AcceleratorStream stream, ArrayView1D <T, TStride> view, T value) where T : unmanaged where TStride : struct, IStride1D => accelerator.CreateInitializer <T, TStride>()( stream, view, value);
public void Init() { var init = Acc.CreateInitializer <Vector2>(); buffer1 = Acc.Allocate <Vector2>(Items); init(Acc.DefaultStream, buffer1, Vector2.One); buffer2 = Acc.Allocate <Vector2>(Items); init(Acc.DefaultStream, buffer2, Vector2.One); run = Acc.LoadAutoGroupedStreamKernel <ILGPU.Index, ArrayView <Vector2>, ArrayView <Vector2> >(ilgpu_test); idx = new ILGPU.Index(Items); }
/// <summary> /// Performs an initialization on the given view. /// </summary> /// <typeparam name="T">The element type.</typeparam> /// <param name="accelerator">The accelerator.</param> /// <param name="stream">The accelerator stream.</param> /// <param name="view">The element view.</param> /// <param name="value">The target value.</param> public static void Initialize <T>( this Accelerator accelerator, AcceleratorStream stream, ArrayView <T> view, T value) where T : struct { accelerator.CreateInitializer <T>()( stream, view, value); }
/// <summary> /// Creates a new instance of a atomic reduction handler. /// </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> /// <returns>The created reduction handler.</returns> public static Reduction <T, TShuffleDown, TReduction> CreateReduction <T, TShuffleDown, TReduction>( this Accelerator accelerator) where T : struct where TShuffleDown : struct, IShuffleDown <T> where TReduction : struct, IReduction <T> { var kernel = accelerator.LoadKernel <Action <AcceleratorStream, GroupedIndex, ArrayView <T>, ArrayView <T>, TShuffleDown, TReduction> >( ReductionImpl <T, TShuffleDown, TReduction, DefaultReductionFinalizer <T, TReduction> > .KernelMethod); var initializer = accelerator.CreateInitializer <T>(); return((stream, input, output, temp, shuffleDown, reduction) => { if (!input.IsValid) { throw new ArgumentNullException(nameof(input)); } if (input.Length < 1) { throw new ArgumentOutOfRangeException(nameof(input)); } if (!output.IsValid) { throw new ArgumentNullException(nameof(output)); } if (output.Length < 1) { throw new ArgumentOutOfRangeException(nameof(output)); } if (!temp.IsValid) { throw new ArgumentNullException(nameof(temp)); } var dimension = ComputeReductionDimension(accelerator, input.Length); if (temp.Length < dimension.GroupIdx) { throw new ArgumentOutOfRangeException(nameof(temp), $"Temp space must be at least {dimension.GroupIdx} elements large"); } initializer(stream, temp, reduction.NeutralElement); kernel(stream, dimension, input, temp, shuffleDown, reduction); kernel(stream, new GroupedIndex(1, dimension.GroupIdx), temp, output, shuffleDown, reduction); }); }
/// <summary> /// Creates a new instance of a reduction handler. /// </summary> /// <typeparam name="T">The underlying type of the reduction.</typeparam> /// <typeparam name="TStride">The 1D stride of the source view.</typeparam> /// <typeparam name="TReduction">The type of the reduction logic.</typeparam> /// <param name="accelerator">The accelerator.</param> /// <returns>The created reduction handler.</returns> public static Reduction <T, TStride> CreateReduction <T, TStride, TReduction>( this Accelerator accelerator) where T : unmanaged where TStride : struct, IStride1D where TReduction : struct, IScanReduceOperation <T> { var initializer = accelerator.CreateInitializer <T, Stride1D.Dense>(); var reductionKernel = accelerator.LoadGridStrideKernel < ReductionImplementation <T, TStride, TReduction> >(); return((stream, input, output) => { if (!input.IsValid) { throw new ArgumentNullException(nameof(input)); } if (input.Length < 1) { throw new ArgumentOutOfRangeException(nameof(input)); } if (!output.IsValid) { throw new ArgumentNullException(nameof(output)); } if (output.Length < 1) { throw new ArgumentOutOfRangeException(nameof(output)); } // Ensure a single element in the ouput view output = output.SubView(0, 1); TReduction reduction = default; initializer(stream, output, reduction.Identity); reductionKernel( stream, input.Length, new ReductionImplementation <T, TStride, TReduction>( input, output)); }); }