Skip to content

Commit

Permalink
Merge pull request #20 from Araq/araq-apply
Browse files Browse the repository at this point in the history
added parMap and parApply
  • Loading branch information
Araq authored Aug 30, 2023
2 parents f982cbc + e32c683 commit 4e73fd0
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
24 changes: 23 additions & 1 deletion src/malebolgia/paralgos.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import malebolgia
template `@!`[T](data: openArray[T]; i: int): untyped =
cast[ptr UncheckedArray[T]](addr data[i])

template parMap*[T](data: var openArray[T]; bulkSize: int; op: untyped) =
template parApply*[T](data: var openArray[T]; bulkSize: int; op: untyped) =
##[ Applies `op` on every element of `data`, `op(data[i)` in parallel.
`bulkSize` specifies how many elements are processed sequentially
and not in parallel because sending a task to a different thread
Expand All @@ -23,6 +23,28 @@ template parMap*[T](data: var openArray[T]; bulkSize: int; op: untyped) =
if i < data.len:
m.spawn worker(data@!i, data.len-i)

template parMap*[T](data: var openArray[T]; bulkSize: int; op: untyped): untyped =
##[ Applies `op` on every element of `data`, `op(data[i)` in parallel.
Produces a new `seq` of `typeof(op(data[i]))`.
`bulkSize` specifies how many elements are processed sequentially
and not in parallel because sending a task to a different thread
is expensive. `bulkSize` should probably be larger than you think but
it depends on how expensive the operation `op` is.]##
proc worker[Tin, Tout](a: ptr UncheckedArray[Tin];
dest: ptr UncheckedArray[Tout]; until: int) =
for i in 0..<until: dest[i] = op(a[i])

var m = createMaster()
var result = newSeq[typeof(op(data[0]))](data.len)
m.awaitAll:
var i = 0
while i+bulkSize <= data.len:
m.spawn worker(data@!i, result@!i, bulkSize)
i += bulkSize
if i < data.len:
m.spawn worker(data@!i, result@!i, data.len-i)
result

template parReduce*[T](data: openArray[T]; bulkSize: int;
op: untyped): untyped =
##[ Computes in parallel:
Expand Down
5 changes: 4 additions & 1 deletion tests/tparalgos.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ var testData: seq[int] = @[]
for i in 0..<10_000: testData.add i

proc mul4(x: var int) = x *= 4
parMap(testData, 600, mul4)
parApply(testData, 600, mul4)

for i in 0..<10_000: assert testData[i] == i*4

Expand All @@ -22,3 +22,6 @@ for i in 0..<10_000: haystack.add i
template predicate(x): untyped = x == 1000
let idx = parFind(haystack, 600, predicate)
assert idx == 1000

let transformed = parMap(testData, 600, `$`)
assert transformed[9] == $(9*4)

0 comments on commit 4e73fd0

Please sign in to comment.