internal static void WarpShuffleDownKernel( Index1 index, ArrayView <int> data, int shiftAmount) { data[index] = Warp.ShuffleDown(Warp.LaneIdx, shiftAmount); }
internal static void WarpShuffleDownKernel( Index1D index, ArrayView1D <int, Stride1D.Dense> data, int shiftAmount) { data[index] = Warp.ShuffleDown(Warp.LaneIdx, shiftAmount); }
/// <summary> /// Performs a shuffle operation. It returns the value of the variable /// in the context of the lane with the id current lane + delta. /// </summary> /// <param name="variable">The source variable to shuffle.</param> /// <param name="delta">The delta to add to the current lane.</param> /// <returns>The value of the variable in the scope of the desired lane.</returns> public unsafe long ShuffleDown(long variable, int delta) { var result = new Int2(); var ptr = (Int2 *)&variable; result.X = Warp.ShuffleDown(ptr->X, delta); result.Y = Warp.ShuffleDown(ptr->Y, delta); return(*(long *)&result); }
/// <summary> /// Performs a shuffle operation. It returns the value of the variable /// in the context of the lane with the id current lane + delta. /// </summary> /// <param name="variable">The source variable to shuffle.</param> /// <param name="delta">The delta to add to the current lane.</param> /// <returns>The value of the variable in the scope of the desired lane.</returns> public long ShuffleDown(long variable, int delta) { var source = Unsafe.As <long, Int2>(ref variable); var result = new Int2() { X = Warp.ShuffleDown(source.X, delta), Y = Warp.ShuffleDown(source.Y, delta), }; return(Unsafe.As <Int2, long>(ref result)); }
/// <summary> /// Explicitly grouped kernels receive an index type (first parameter) of type: /// <see cref="GroupedIndex"/>, <see cref="GroupedIndex2"/> or <see cref="GroupedIndex3"/>. /// Note that you can use warp-shuffle functionality only within /// explicitly-grouped kernels. Previously, it was required to use one of the predefined /// shuffle overloads. If the desired function was not available, you had to create a /// custom shuffle operation implementation. The current ILGPU version emits the required /// shuffle instructions (even for complex data types) automatically. /// </summary> /// <param name="index">The current thread index.</param> /// <param name="dataView">The view pointing to our memory buffer.</param> static void ShuffleDownKernel( ArrayView <int> dataView) // A view to a chunk of memory (1D in this case) { // Use native shuffle-down functionality to shuffle the // given value by a delta of 2 lanes int value = Group.IdxX; value = Warp.ShuffleDown(value, 2); dataView[Grid.GlobalIndex.X] = value; }
public static T Reduce <T, TReduction>(T value) where T : unmanaged where TReduction : IScanReduceOperation <T> { TReduction reduction = default; for (int laneOffset = Warp.WarpSize / 2; laneOffset > 0; laneOffset >>= 1) { var shuffled = Warp.ShuffleDown(value, laneOffset); value = reduction.Apply(value, shuffled); } return(value); }
/// <summary> /// Explicitly grouped kernels receive an index type (first parameter) of type: /// <see cref="GroupedIndex"/>, <see cref="GroupedIndex2"/> or <see cref="GroupedIndex3"/>. /// Note that you can use warp-shuffle functionality only within /// explicitly-grouped kernels. /// </summary> /// <param name="index">The current thread index.</param> /// <param name="dataView">The view pointing to our memory buffer.</param> static void ShuffleDownKernel( GroupedIndex index, // The grouped thread index (1D in this case) ArrayView <int> dataView) // A view to a chunk of memory (1D in this case) { // Compute the global 1D index for accessing the data view var globalIndex = index.ComputeGlobalIndex(); // Use native shuffle-down functionality to shuffle the // given value by a delta of 2 lanes int value = index.GroupIdx; value = Warp.ShuffleDown(value, 2); dataView[globalIndex] = value; }