anchor.diff:                  d <- d >>> 1
   
               if lgid < inputSize then
  -                output.[outputOffset + lgid * outputDelta] <- mem.[llid]
  +                outputData.[outputOffset + lgid * outputDelta] <- mem.[llid]
               if rgid < inputSize then
  -                output.[outputOffset + rgid * outputDelta] <- mem.[rlid]
  +                outputData.[outputOffset + rgid * outputDelta] <- mem.[rlid]
   
           }
           
       [<LocalSize(X = halfScanSize)>]
  -    let addParentSum (dataLength : int) (offset : int) (scan : float[]) (data : float[]) =
  +    let addParentSum (inputData : int[]) (inputOffset : int) (inputDelta : int) (outputData : int[]) (outputOffset : int) (outputDelta : int) (groupSize : int) (count : int) =
           compute {
  -            let id = offset + getGlobalId().X
  -            let pid = id / offset - 1
  -            let s = scan.[pid]
  -
  -
  -            if id < dataLength then
  -                data.[id] <- data.[id] + s
  +            let id = getGlobalId().X + groupSize
  +
  +            if id < count then
  +                let block = id / groupSize - 1
  +              
  +                let iid = inputOffset + block * inputDelta
  +                let oid = outputOffset + id * outputDelta
  +
  +                if id % groupSize <> groupSize - 1 then
  +                    outputData.[oid] <- outputData.[oid] + inputData.[iid]
   
           }
   
  
positive.code: 
          }
  
  
      let testreduce8() =
          use app = new HeadlessVulkanApplication(false)
          let device = app.Device
          let shader = device |> ComputeShader.ofFunction scan2048
          let pool = device.CreateDescriptorPool(1 <<< 20, 1 <<< 20)
         
          let cnt = 1 <<< 20
          let input = ArrayBuffer (Array.init cnt (fun _ -> 1.0f))
          let output = device.CreateBuffer(VkBufferUsageFlags.StorageBufferBit ||| VkBufferUsageFlags.TransferSrcBit, int64 cnt * 4L)
          let mappable = device.HostMemory |> Buffer.create VkBufferUsageFlags.TransferDstBit (int64 cnt * 4L)
  
          //(inputOffset : int) (inputDelta : int) (inputSize : int) (input : float[]) (outputOffset : int) (outputDelta : int) (res : float[])
          let args0 = ComputeShader.newInputBinding shader pool
          args0.["inputOffset"] <- 0
          args0.["inputDelta"] <- 1
          args0.["inputSize"] <- cnt
          args0.["input"] <- input
          args0.["outputOffset"] <- 0
          args0.["outputDelta"] <- 1
          args0.["output"] <- output
          args0.Flush()
          
          let temp = device.CreateBuffer(VkBufferUsageFlags.StorageBufferBit ||| VkBufferUsageFlags.TransferSrcBit, int64 (cnt / 2048) * 4L)
          let args1 = ComputeShader.newInputBinding shader pool
          args1.["inputOffset"] <- scanSize
          args1.["inputDelta"] <- scanSize
          args1.["inputSize"] <- (cnt - scanSize) / scanSize
          args1.["input"] <- output
          args1.["outputOffset"] <- 0
          args1.["outputDelta"] <- 1
          args1.["output"] <- temp
          args1.Flush()
  
          
          let shader2 = device |> ComputeShader.ofFunction addParentSum
          
          let argsAdd = ComputeShader.newInputBinding shader2 pool
          argsAdd.["scan"] <- temp
          argsAdd.["data"] <- output
          argsAdd.["dataLength"] <- cnt / scanSize
          argsAdd.["offset"] <- scanSize
          argsAdd.Flush()
  
          device.perform {
              do! Command.Bind shader
  
              do! Command.SetInputs args0
              do! Command.Dispatch(cnt / scanSize)
  
              do! Command.SetInputs args1
              do! Command.Dispatch(cnt / scanSize / scanSize)
  
              do! Command.Bind shader2
              do! Command.SetInputs argsAdd
              do! Command.Dispatch((cnt - scanSize) / halfScanSize)
  
              do! Command.Copy(output, mappable)
          }
  
          let result : float32[] = Array.zeroCreate cnt
          let gc = GCHandle.Alloc(result, GCHandleType.Pinned)
          mappable.Memory.Mapped (fun src -> Marshal.Copy(src, gc.AddrOfPinnedObject(), int64 cnt * 4L))
          gc.Free()
  
          let check = Array.init cnt (fun i -> 1 + (i % 2048) |> float32)
          if check = result then
              printfn "OK"
          else
              printfn "ERROR:"
              for i in 0 .. cnt - 1 do
                  if result.[i] <> check.[i] then
                      printfn "  %d: %A vs %A" i result.[i] check.[i]
  
          args0.Dispose()
          args1.Dispose()
          argsAdd.Dispose()
          device.Delete output
          device.Delete mappable
          ComputeShader.delete shader
          device.Delete pool
  
  
negative.code:         }
  
      [<Literal>]
      let scanSize = 192
  
      [<Literal>]
      let halfScanSize = 96
  
      [<LocalSize(X = halfScanSize)>]
      let scan2048 (inputOffset : int) (inputDelta : int) (inputSize : int) (inputData : int[]) (outputOffset : int) (outputDelta : int) (outputData : int[]) =
          compute {
              let mem : int[] = allocateShared scanSize
              let gid = getGlobalId().X
  
              let gid0 = gid
  