From: Luke Kenneth Casson Leighton Date: Tue, 21 Jun 2022 13:08:08 +0000 (+0100) Subject: add yield version of parallel-reduce X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=13c4a19e93caf4dc817c508f70f3af42749a7a87;p=libreriscv.git add yield version of parallel-reduce --- diff --git a/openpower/sv/preduce.py b/openpower/sv/preduce.py index 815def6b7..5fb4f26f6 100644 --- a/openpower/sv/preduce.py +++ b/openpower/sv/preduce.py @@ -1,7 +1,7 @@ from copy import copy def preduce(vl, vec, pred): - vec = copy(vec) # must not damage predicate + vec = copy(vec) pred = copy(pred) # must not damage predicate step = 1 print(" start", step, pred, vec) @@ -18,10 +18,12 @@ def preduce(vl, vec, pred): print(" row", step, pred, vec) return vec + def preducei(vl, vec, pred): + vec = copy(vec) pred = copy(pred) # must not damage predicate step = 1 - ix = list(range(vl)) + ix = list(range(vl)) # indices move rather than copy data print(" start", step, pred, vec) while step < vl: step *= 2 @@ -33,9 +35,34 @@ def preducei(vl, vec, pred): if pred[ci] and other_pred: vec[ci] += vec[oi] elif other_pred: - ix[i] = oi + ix[i] = oi # leave data in-place, copy index instead pred[ci] |= other_pred print(" row", step, pred, vec, ix) + return vec + + +def preduce_yield(vl, vec, pred): + pred = copy(pred) # must not damage predicate + step = 1 + ix = list(range(vl)) + while step < vl: + step *= 2 + for i in range(0, vl, step): + other = i + step // 2 + ci = ix[i] + oi = ix[other] if other < vl else None + other_pred = other < vl and pred[oi] + if pred[ci] and other_pred: + yield ci, oi + elif other_pred: + ix[i] = oi + pred[ci] |= other_pred + + +def preduce_y(vl, vec, pred): + for i, other in preduce_yield(vl, vec, pred): + vec[i] += vec[other] + if __name__ == '__main__': vec = [1, 2, 3, 4, 9, 5, 6] @@ -43,8 +70,24 @@ if __name__ == '__main__': print (vec) res = preduce(len(vec), vec, prd) print (res) - preducei(len(vec), vec, prd) + res2 = preducei(len(vec), vec, prd) + print (res2) + print () + preduce_y(len(vec), vec, prd) + print (vec) + print () + assert vec == res2 + + vec = [1, 2, 3, 4, 9, 5, 6] + prd = [1, 0, 0, 1, 1, 0, 1] + print (vec) + res = preduce(len(vec), vec, prd) + print (res) + res2 = preducei(len(vec), vec, prd) + print (res2) + print () + preduce_y(len(vec), vec, prd) print (vec) print () - assert vec == res + assert vec == res2