Nested reductions -- what is the most idiomatic way to write these in Chapel?

Viewed 156

Chapel reductions currently ignore the initial values of variables. That means this code

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

writeln(x);

returns 10 and not 30, as this user naively thought. While this behavior is fine (and it is documented in the notes on reduction clauses -- I just didn't think hard about it), it turns out that if I want to get 30 (by accumulating across both loops), I need to actually do the sum by hand. I think it would be quite elegant and symmetric for for loops to also have a reduce intent.... i.e. I'd 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);

Note that even in the case of summing numbers, I need to introduce a temporary variable. For max/min like operations, one needs to be even more careful.

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

UPDATE: The more I think about this, it's not obvious that my proposed code would work in the case that the outer for was replaced by a forall. I think the issue is that the variables are task-local and not iteration-local, so that the reduction would only occur over tasks. So one would still need a separate internal reduction step. What this would remove is the need for a temporary variable.

I think the more overarching question is what the correct way to do these sorts of nested reductions is...

1 Answers
Related