anchor.diff:              if id < srcCnt then
                   dst.[dstOffset + id * dstDelta] <- (%map) id src.[srcOffset + id * srcDelta]
           }
  +
  +    [<Inline>]
  +    let mk2d (dim : int) (x : int) (y : int) =
  +        if dim = 0 then V2i(x,y)
  +        else V2i(y,x)
  +
  +    [<LocalSize(X = halfScanSize)>]
  +    let scanImageKernel2d (dim : int) (add : Expr<V4d -> V4d -> V4d>) (outputImage : Image2d<Formats.r32f>) =
  +        compute {
  +            let mem : V4d[] = allocateShared scanSize
  +            let gid = getGlobalId().X
  +            let group = getWorkGroupId().X
  +            let inputSize = inputImage2d.Size.[dim]
  +            let y = getGlobalId().Y
  +
  +            if y < inputImage2d.Size.[1 - dim] then
  +                let gid0 = gid
  +                let lid0 =  getLocalId().X
  +
  +                let lai = lid0
  +                let lbi = lid0 + halfScanSize
  +                let ai  = 2 * gid0 - lid0 
  +                let bi  = ai + halfScanSize 
  +
  +                if ai < inputSize then mem.[lai] <- inputImage2d.[mk2d dim ai y]
  +                if bi < inputSize then mem.[lbi] <- inputImage2d.[mk2d dim bi y]
  +
  +                let lgid = 2 * gid0
  +                let rgid = lgid + 1
  +                let llid = 2 * lid0
  +                let rlid = llid + 1
  +
  +                let mutable offset = 1
  +                let mutable d = halfScanSize
  +                while d > 0 do
  +                    barrier()
  +                    if lid0 < d then
  +                        let ai = offset * (llid + 1) - 1
  +                        let bi = offset * (rlid + 1) - 1
  +                        mem.[bi] <- (%add) mem.[ai] mem.[bi]
  +                    d <- d >>> 1
  +                    offset <- offset <<< 1
  +
  +                d <- 2
  +                offset <- offset >>> 1
  +
  +                while d < scanSize do
  +                    offset <- offset >>> 1
  +                    barrier()
  +                    if lid0 < d - 1 then
  +                        let ai = offset*(llid + 2) - 1
  +                        let bi = offset*(rlid + 2) - 1
  +
  +                        mem.[bi] <- (%add) mem.[bi] mem.[ai]
  +
  +                    d <- d <<< 1
  +                barrier()
  +
  +                if lgid < inputSize then
  +                    outputImage.[mk2d dim lgid y] <- mem.[llid]
  +                    //(%write) outputImage lgid y mem.[llid]
  +
  +                if rgid < inputSize then
  +                    outputImage.[mk2d dim rgid y] <- mem.[rlid]
  +                    //(%write) outputImage rgid y mem.[rlid]
  +        }
  +
  +
   
   
   type private Map<'a, 'b when 'a : unmanaged and 'b : unmanaged>(runtime : IComputeRuntime, map : Expr<int -> 'a -> 'b>) =
  
positive.code:             let reducer = getReducer add
              new MapReduce<'a, 'b>(runtime, reducer, map, add)
          )
  
      let getImageMapReducer (map : Expr<V3i -> V4f -> 'b>) (add : Expr<'b -> 'b -> 'b>) =
          mapReduceCache.GetOrCreate(map, add, fun map add -> 
  
negative.code:     let reduceCache = ExpressionCache()
      let mapReduceCache = ExpressionCache()
      let mapReduceImageCache = ExpressionCache()
      
      let scanImage2dCache = ExpressionCache()
  
  
  
      let getMapper (map : Expr<int -> 'a -> 'b>) = mapCache.GetOrCreate(map, fun map -> new Map<'a, 'b>(runtime, map))
  