@@ -270,3 +270,75 @@ module PrefixSum =
270270 fun ( processor : MailboxProcessor < _ >) ( inputArray : ClArray < int >) ->
271271
272272 scan processor inputArray 0
273+
274+
275+ module ByKey =
276+ let private sequentialSegments opWrite ( clContext : ClContext ) workGroupSize opAdd zero =
277+
278+ let kernel =
279+ <@ fun ( ndRange : Range1D ) lenght uniqueKeysCount ( values : ClArray < 'a >) ( keys : ClArray < int >) ( offsets : ClArray < int >) ->
280+ let gid = ndRange.GlobalID0
281+
282+ if gid < uniqueKeysCount then
283+ let sourcePosition = offsets.[ gid]
284+ let sourceKey = keys.[ sourcePosition]
285+
286+ let mutable currentSum = zero
287+ let mutable previousSum = zero
288+
289+ let mutable currentPosition = sourcePosition
290+
291+ while currentPosition < lenght
292+ && keys.[ currentPosition] = sourceKey do
293+
294+ previousSum <- currentSum
295+ currentSum <- (% opAdd) currentSum values.[ currentPosition]
296+
297+ values.[ currentPosition] <- (% opWrite) previousSum currentSum
298+
299+ currentPosition <- currentPosition + 1 @>
300+
301+ let kernel = clContext.Compile kernel
302+
303+ fun ( processor : MailboxProcessor < _ >) uniqueKeysCount ( values : ClArray < 'a >) ( keys : ClArray < int >) ( offsets : ClArray < int >) ->
304+
305+ let kernel = kernel.GetKernel()
306+
307+ let ndRange =
308+ Range1D.CreateValid( values.Length, workGroupSize)
309+
310+ processor.Post(
311+ Msg.MsgSetArguments
312+ ( fun () -> kernel.KernelFunc ndRange values.Length uniqueKeysCount values keys offsets)
313+ )
314+
315+ processor.Post( Msg.CreateRunMsg<_, _> kernel)
316+
317+ /// <summary >
318+ /// Exclude scan by key.
319+ /// </summary >
320+ /// <example >
321+ /// <code >
322+ /// let arr = [ | 1; 1; 1; 1; 1; 1|]
323+ /// let keys = [ | 1; 2; 2; 2; 3; 3 |]
324+ /// ...
325+ /// > val result = [ | 0; 0; 1; 2; 0; 1 |]
326+ /// </code>
327+ /// </example>
328+ let sequentialExclude clContext =
329+ sequentialSegments ( Map.fst ()) clContext
330+
331+ /// <summary >
332+ /// Include scan by key.
333+ /// </summary >
334+ /// <example >
335+ /// <code >
336+ /// let arr = [ | 1; 1; 1; 1; 1; 1|]
337+ /// let keys = [ | 1; 2; 2; 2; 3; 3 |]
338+ /// ...
339+ /// > val result = [ | 1; 1; 2; 3; 1; 2 |]
340+ /// </code>
341+ /// </example>
342+ let sequentialInclude clContext =
343+ sequentialSegments ( Map.snd ()) clContext
344+
0 commit comments