For param (legal) VS foreach (illegal)

The following is legal

proc advance(dt) {
  param n = numBodies-1;

  for param i in 0..n {
    const pi = bodies[i].pos; // rip 'pos' out of loop
    const mi = bodies[i].mass; // rip 'mass' out of loop
    var vi = bodies[i].vel; // accumulate within loop

    for param j in i+1..n {
      ref bj = bodies[j];
      const dp = pi - bj.pos;
      const dpsq = sumOfSquares(dp);
      const mag = dt / (dpsq * sqrt(dpsq));

      vi -= dp * bj.mass * mag; // line 111
      bj.vel += dp * mi * mag; // line 112
    }
    bodies[i].vel = vi; // line 114
    bodies[i].pos = pi + vi * dt; // line 115
  }
}

Change the for param to foreach and it is illegal:

chpl --fast n4.chpl
n4.chpl:97: In function 'advance':
n4.chpl:111: error: cannot assign to const variable
n4.chpl:105: note: The shadow variable 'vi' is constant due to task intents in this loop
n4.chpl:112: error: cannot assign to const variable
n4.chpl:114: error: cannot assign to const variable
n4.chpl:100: note: The shadow variable 'bodies' is constant due to task intents in this loop
n4.chpl:115: error: cannot assign to const variable
n4.chpl:100: note: The shadow variable 'bodies' is constant due to task intents in this loop
  n4.chpl:77: called as advance(dt: real(64))

What am I doing wrong?

Hello Damian,

foreach loops assume that the iterations can be executed in any order. Therefore scalar outer variables are considered constant within the loop, while arrays can be modified regardless. This matches the behavior of forall loops.

So the error for vi makes sense. To address it, how about a reduce intent? We currently do not support reduce intents on foreach loops, we do on forall loops, how for GPUs as well, see Add support for reduce intents and expressions on GPU by e-kayrakli · Pull Request #24787 · chapel-lang/chapel · GitHub

The error for bodies does not make sense to me. Also, I am not observing it. Could you perhaps post a complete reproducer and the Chapel version you are using?

Vass

I will fix up the issue you mentioned with the foreach and see if that fixes it.

I will post later today. Thanks for the help (over the weekend). t is the NBODY benchmark. Well my ttake on it.