/// <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> /// Computes the required number of temp-storage elements for a radix sort /// operation and the given data length. /// </summary> /// <typeparam name="T">The underlying type of the sort operation.</typeparam> /// <typeparam name="TRadixSortOperation"> /// The type of the radix-sort operation. /// </typeparam> /// <param name="accelerator">The accelerator.</param> /// <param name="dataLength">The number of data elements to sort.</param> /// <returns> /// The required number of temp-storage elements in 32 bit ints. /// </returns> public static Index1 ComputeRadixSortTempStorageSize <T, TRadixSortOperation>( this Accelerator accelerator, Index1 dataLength) where T : unmanaged where TRadixSortOperation : struct, IRadixSortOperation <T> { Index1 tempScanMemory = accelerator.ComputeScanTempStorageSize <T>(dataLength); int numGroups; if (accelerator.AcceleratorType == AcceleratorType.CPU) { numGroups = accelerator.MaxNumThreads; } else { var(gridDim, _) = accelerator.ComputeGridStrideLoopExtent( dataLength, out int numIterationsPerGroup); numGroups = gridDim * numIterationsPerGroup; } int numIntTElements = Interop.ComputeRelativeSizeOf <int, T>(dataLength); const int unrollFactor = 4; return(numGroups * unrollFactor * 2 + numIntTElements + tempScanMemory); }
/// <summary> /// Creates a kernel to calculate the histogram on a supplied view. /// </summary> /// <typeparam name="T">The input view element type.</typeparam> /// <typeparam name="TIndex">The input view index type.</typeparam> /// <typeparam name="TBinType">The histogram bin type.</typeparam> /// <typeparam name="TIncrementor"> /// The operation to increment the value of the bin. /// </typeparam> /// <typeparam name="TLocator"> /// The operation to compute the bin location. /// </typeparam> /// <param name="accelerator">The accelerator.</param> /// <returns>The created histogram handler.</returns> public static Histogram <T, TIndex, TBinType> CreateHistogram < T, TIndex, TBinType, TIncrementor, TLocator>( this Accelerator accelerator) where T : unmanaged where TIndex : unmanaged, IIndex, IGenericIndex <TIndex> where TBinType : unmanaged where TIncrementor : struct, IIncrementOperation <TBinType> where TLocator : struct, IComputeMultiBinOperation <T, TBinType, TIncrementor> { var kernel = accelerator.LoadKernel < HistogramDelegate < T, TBinType, TIncrementor, TLocator> >( HistogramKernelMethod.MakeGenericMethod( typeof(T), typeof(TBinType), typeof(TIncrementor), typeof(TLocator))); return((stream, view, histogram, histogramOverflow) => { var input = view.AsLinearView(); var(gridDim, groupDim) = accelerator.ComputeGridStrideLoopExtent( input.Length, out int numIterationsPerGroup); int numVirtualGroups = gridDim * numIterationsPerGroup; int lengthInformation = XMath.DivRoundUp(input.Length, groupDim) * groupDim; kernel( stream, (gridDim, groupDim), input, histogram, histogramOverflow, lengthInformation); }); }
private static void FindHull( Point[] points, Point p1, Point p2, int side, HashSet <Point> result, Accelerator accelerator, ArrayView <Point> view) { var(gridDim, groupDim) = accelerator.ComputeGridStrideLoopExtent(points.Length, out _); using var output = accelerator.Allocate <DataBlock <int, float> >(gridDim); var kernel = accelerator.LoadStreamKernel < ArrayView <Point>, int, Point, Point, ArrayView <DataBlock <int, float> > >(FindMaxIndexKernel); kernel(new KernelConfig(gridDim, groupDim), view, side, p1, p2, output); accelerator.Synchronize(); var maxIndex = -1; var maxDistance = 0f; var candidates = output.GetAsArray(); foreach (var candidate in candidates) { if (candidate.Item1 < 0) { continue; } FindMaxIndex(p1, p2, points[candidate.Item1], side, candidate.Item1, ref maxIndex, ref maxDistance); } if (maxIndex < 0) { result.Add(p1); result.Add(p2); return; } var newSide = Side(points[maxIndex], p1, p2); FindHull(points, points[maxIndex], p1, -newSide, result, accelerator, view); FindHull(points, points[maxIndex], p2, newSide, result, accelerator, view); }
/// <summary> /// Creates a kernel to calculate the histogram on a supplied view /// (without overflow checking). /// </summary> /// <typeparam name="T">The input view element type.</typeparam> /// <typeparam name="TStride">The input view stride.</typeparam> /// <typeparam name="TBinType">The histogram bin type.</typeparam> /// <typeparam name="TIncrementor"> /// The operation to increment the value of the bin. /// </typeparam> /// <typeparam name="TLocator"> /// The operation to compute the bin location. /// </typeparam> /// <param name="accelerator">The accelerator.</param> /// <returns>The created histogram handler.</returns> public static HistogramUnchecked <T, TStride, TBinType> CreateHistogramUnchecked < T, TStride, TBinType, TIncrementor, TLocator>( this Accelerator accelerator) where T : unmanaged where TStride : unmanaged, IStride1D where TBinType : unmanaged where TIncrementor : struct, IIncrementOperation <TBinType> where TLocator : struct, IComputeMultiBinOperation <T, TBinType, TIncrementor> { var kernel = accelerator.LoadKernel < HistogramUncheckedDelegate < T, TStride, TBinType, TIncrementor, TLocator> >( HistogramUncheckedKernelMethod.MakeGenericMethod( typeof(T), typeof(TStride), typeof(TBinType), typeof(TIncrementor), typeof(TLocator))); return((stream, view, histogram) => { if (!view.IsValid) { throw new ArgumentNullException(nameof(view)); } if (view.Length < 1) { throw new ArgumentOutOfRangeException(nameof(view)); } if (!histogram.IsValid) { throw new ArgumentNullException(nameof(histogram)); } if (histogram.Length < 1) { throw new ArgumentOutOfRangeException(nameof(histogram)); } if (view.Length > int.MaxValue || histogram.Length > int.MaxValue) { throw new NotSupportedException( ErrorMessages.NotSupportedArrayView64); } int numElements = view.IntExtent; var(gridDim, groupDim) = accelerator.ComputeGridStrideLoopExtent( numElements, out int numIterationsPerGroup); int lengthInformation = XMath.DivRoundUp(numElements, groupDim) * groupDim; kernel( stream, (gridDim, groupDim), view, histogram, lengthInformation); }); }
/// <summary> /// Creates a kernel to calculate the histogram on a supplied view. /// </summary> /// <typeparam name="T">The input view element type.</typeparam> /// <typeparam name="TIndex">The input view index type.</typeparam> /// <typeparam name="TBinType">The histogram bin type.</typeparam> /// <typeparam name="TIncrementor"> /// The operation to increment the value of the bin. /// </typeparam> /// <typeparam name="TLocator"> /// The operation to compute the bin location. /// </typeparam> /// <param name="accelerator">The accelerator.</param> /// <returns>The created histogram handler.</returns> public static Histogram <T, TIndex, TBinType> CreateHistogram < T, TIndex, TBinType, TIncrementor, TLocator>( this Accelerator accelerator) where T : unmanaged where TIndex : unmanaged, IIndex, IGenericIndex <TIndex> where TBinType : unmanaged where TIncrementor : struct, IIncrementOperation <TBinType> where TLocator : struct, IComputeMultiBinOperation <T, TBinType, TIncrementor> { var kernel = accelerator.LoadKernel < HistogramDelegate < T, TBinType, TIncrementor, TLocator> >( HistogramKernelMethod.MakeGenericMethod( typeof(T), typeof(TBinType), typeof(TIncrementor), typeof(TLocator))); return((stream, view, histogram, histogramOverflow) => { if (!view.IsValid) { throw new ArgumentNullException(nameof(view)); } if (view.Length < 1) { throw new ArgumentOutOfRangeException(nameof(view)); } if (!histogram.IsValid) { throw new ArgumentNullException(nameof(histogram)); } if (histogram.Length < 1) { throw new ArgumentOutOfRangeException(nameof(histogram)); } if (!histogramOverflow.IsValid) { throw new ArgumentNullException(nameof(histogramOverflow)); } if (histogramOverflow.Length < 1) { throw new ArgumentOutOfRangeException(nameof(histogramOverflow)); } if (view.Length > int.MaxValue || histogram.Length > int.MaxValue) { throw new NotSupportedException( ErrorMessages.NotSupportedArrayView64); } var input = view.AsLinearView(); var(gridDim, groupDim) = accelerator.ComputeGridStrideLoopExtent( input.Length, out int numIterationsPerGroup); int numVirtualGroups = gridDim * numIterationsPerGroup; int lengthInformation = XMath.DivRoundUp(input.Length, groupDim) * groupDim; kernel( stream, (gridDim, groupDim), input, histogram, histogramOverflow, lengthInformation); }); }