Nested abbreviations - what is the most idiomatic way to write them in the Chapel?

Chapel abbreviations currently ignore the initial values ​​of variables. This means that this code

var x: int; for i in 1..3 { forall j in 1..10 with (+ reduce x) { x += 1; } } writeln(x); 

returns 10, not 30, as this user naively thought. Although this behavior is great (and it’s documented in the notes on the reduction proposals — I just didn’t think about it), it turns out that if I want to get 30 (by accumulating over both loops), I need to actually do the amount manually. I think it would be rather elegant and symmetrical for for loops to also have the intention of reduce .... i.e. I would like to write

 var x: int; for i in 1..3 with (+ reduce x) { forall j in 1..10 with (+ reduce x) { x += 1; } } writeln(x); 

Please note that even when summing numbers, I need to enter a temporary variable. For max / min, like operations, you need to be even more careful.

Is there a reason not to support reduce intents inside loops? Alternatively, is there a more idiomatic way (Chapel-rrific) for this?

UPDATE. The more I think about it, the more obvious that my proposed code will work if the external for been replaced by forall . I think the problem is that the variables are local, not iterative, local, so the reduction will only happen on tasks. Thus, a separate internal recovery step will still be required. This may be due to the need for a temporary variable.

I think the more comprehensive question is that the right way to do these kinds of nested abbreviations is ...

+5
source share
1 answer

It seems to me that this oversight in Chaplin’s design is holding back the intention. In particular, although I consider it advisable that each task ignores the original value of the variable when initializing its personal copy of the reduction variable of identity (as you have noticed at the moment), I believe that the contributions of the tasks should be combined back into the original variable at the end of the parallel loop , and not just rewrite this original value, since they are combined with each other. This would make your initial attempt to work as you expected, and would also keep track of what OpenMP does, as suggested in the following C example, which gets 35 as the result:

 #include <stdio.h> #include <omp.h> int main(int argc, char* argv[]) { int tot = 5; for (int i=0; i<3; i++) { #pragma omp parallel for reduction(+:tot) for (int j=0; j<10; j++) { tot += 1; } } printf("tot is: %d\n", tot); } 

I would recommend filing a bug / function request protecting this behavior in the Chapel GitHub page .

As with Chapel 1.15.0, one way around this would be to manually reduce it in a sequential loop:

 config var tot: int = 5; for i in 1..3 { var subtot: int; forall j in 1..10 with (+ reduce subtot) do subtot += 1; tot += subtot; } writeln("tot is: ", tot); 
+5
source

Source: https://habr.com/ru/post/1269846/


All Articles