Пример #1
0
        /// <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);
            });
        }
Пример #2
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>
        /// 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);
            });
        }
Пример #4
0
        /// <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);
                }
            });
        }
Пример #5
0
        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);
        }
Пример #6
0
 /// <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);
Пример #7
0
 /// <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);
            });
        }
Пример #11
0
        /// <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));
            });
        }