I have some working code and I'm experimenting with using pointers and slices to achieve the same results.
Here's what I conceptually want to do.
parallel:
for bytn in 0..bprg-1:
.....
var seg_r: seq[uint8] = seg[bytn*Ks..byt*Ks+Ks-1]
spawn residue_sieve(n_row, seg_r, Kmax, Ks, bytn)
sync()t
I want to pass seg_r as a slice, but the compiler squawks with this (it never asked me if I can verify its all good :) ), even when I compile with --boundChecks:on|off.
ssozp13x1d7bparnew512.nim(192, 40) Error: cannot prove: bytn * Ks <= len(seg) + -1 (bounds check)
So I have seg a seq[uint8](m * Ks) array, and I'm processing each of the m rows in parallel.
When I pass in let row_i = bytn * Ks it r/w fine doing seg[row_i + k] inside residue_sieve.
I'm trying to understand how to do the following cases:
I'm doing this to compare timing differences between them in my code (want fastest).
Don't forget that Nim seqs are copy on assignment
If you want slices that share memory you will have to use shallowCopy similar to the following:
var seg_r: seq[uint8]
shallowCopy(seg_r, seg[slice])
seg[slice] might be creating a copy as well so maybe checked what is done in this PR to introduce views/slices of seq.
@jzakiya Too bad there is no seq constructor from raw pointer and size. :-/ This way, you could just make seq which is, in fact, a view of another seq. Hypothetical example:
var s = @[3,1,4,1,5,9,2]
var v = ptrToSeq(s[2].addr, 3)
assert(v == @[4,1,5])
s[2] = 2
assert(v == @[2,1,5])
Seqs own the data they contain, views don't, conceptually there is no safe way to create a seq from a view without a copy.
You can pass zero-copy slices in a parallel statement https://nim-lang.org/docs/manual.html#parallel-spawn-parallel-statement if the parameter is of type openArray.
Slices are optimized so that no copy is performed.
tests/parallel/tparfind.nim has an example:
discard """
output: "500"
"""
import threadpool, sequtils
{.experimental.}
proc linearFind(a: openArray[int]; x, offset: int): int =
for i, y in a:
if y == x: return i+offset
result = -1
proc parFind(a: seq[int]; x: int): int =
var results: array[4, int]
parallel:
if a.len >= 4:
let chunk = a.len div 4
results[0] = spawn linearFind(a[0 ..< chunk], x, 0)
results[1] = spawn linearFind(a[chunk ..< chunk*2], x, chunk)
results[2] = spawn linearFind(a[chunk*2 ..< chunk*3], x, chunk*2)
results[3] = spawn linearFind(a[chunk*3 ..< a.len], x, chunk*3)
result = max(results)
let data = toSeq(0..1000)
echo parFind(data, 500)