parallel collections?  

  RSS

dckc
 dckc
(@dckc)
Member Moderator
Joined:7 months  ago
Posts: 22
06/06/2018 3:02 am  

The iteration and matching section of the tutorial shows iterating through a list -- sequentially.

Any suggestion on how to exploit Rholang concurrency?

I can imagine map and reduce with code duplicated 4x to get 4x parallelism and so on, but that seems kinda ugly.

 

 


ReplyQuote
MichaelBirch
(@michaelbirch)
Member Moderator
Joined:8 months  ago
Posts: 41
06/06/2018 1:10 pm  

The key aspect of the iteration which makes it sequential is that on line 7 a `for` blocks the loop from continuing until the current iteration is complete. If there was no such block then the loop would essentially unroll all at once and you would get fully concurrent execution on the list. That's the beauty of Rholang -- it's concurrent by default and you need to actively try to make it sequential.


ReplyQuote
dckc
 dckc
(@dckc)
Member Moderator
Joined:7 months  ago
Posts: 22
06/06/2018 1:15 pm  

Oh... That example is doing foreach... But what about map or flatmap? That is: how do I get the results back into a list? Or map?


ReplyQuote
MichaelBirch
(@michaelbirch)
Member Moderator
Joined:8 months  ago
Posts: 41
06/06/2018 9:22 pm  

One way of doing it would be to have all the concurrent processes send their results to the same contract, which accumulates them in the structure you want.


ReplyQuote
MichaelBirch
(@michaelbirch)
Member Moderator
Joined:8 months  ago
Posts: 41
06/09/2018 3:49 pm  

Specific example:

contract @["LinkedList", "unorderedParMap"](@list, f, ret) = {
new mapLoop, collect, startCount, completeCount, accCh in {
//Spawn processes, each computing one element
//also processes listening for the result
contract mapLoop(@ll, @count)= {
match ll {
[hd, tl] => {
new ch in { f!(hd, *ch) | for(@r <- ch){collect!(r)} | mapLoop!(tl, count + 1) }
}
_ => { startCount!(count) }
}
} |
//add a result to our accumulating list
contract collect(@result) = {
for(@sc <- startCount; @cc <- completeCount; @acc <- accCh) {
startCount!(sc) |
if (sc == cc + 1) { //all started processes completed!
ret!([result, acc])
} else { //still waiting on some
completeCount!(cc + 1) |
accCh!([result, acc])
}
}
} |
match list {
[_, _] => { mapLoop!(list, 0) | completeCount!(0) | accCh!([]) }
_ => { ret!([]) }
}
}
}

If the order of the list was important then you aggregate the return channels as you go and the have blocking listens on them (essentially map each element to a name which will eventually contain the result and then map the list of names to the computed values).


ReplyQuote
  
Working

Please Login or Register