Beispiel #1
0
        /// <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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #5
0
        /// <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);
            });
        }
Beispiel #6
0
        /// <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);
            });
        }