private static T ComputeScan <T, TScanOperation, TScanImplementation>( T value, out ArrayView <T> sharedMemory) where T : unmanaged where TScanOperation : struct, IScanReduceOperation <T> where TScanImplementation : struct, IScanImplementation <T, TScanOperation> { const int SharedMemoryLength = 32; sharedMemory = SharedMemory.Allocate <T>(SharedMemoryLength); int warpIdx = Warp.WarpIdx; TScanOperation scanOperation = default; // Initialize if (Group.DimX / Warp.WarpSize < SharedMemoryLength) { if (warpIdx < 1) { sharedMemory[Group.IdxX] = scanOperation.Identity; } Group.Barrier(); } TScanImplementation scanImplementation = default; var scannedValue = scanImplementation.Scan(value); if (Warp.IsLastLane) { sharedMemory[warpIdx] = scanImplementation.ScanRightBoundary( scannedValue, value); } Group.Barrier(); // Reduce results again in the first warp if (warpIdx < 1) { ref T sharedBoundary = ref sharedMemory[Group.IdxX]; sharedBoundary = PTXWarpExtensions.InclusiveScan <T, TScanOperation>( sharedBoundary); }
public T Scan(T value) => PTXWarpExtensions.InclusiveScan <T, TScanOperation>(value);