Reverse for loop

This code

const D = {1..5,1..5};
for ij in D do
  writeln(ij)

is short for

for i in D.dim(0) do
  for j in D.dim(1) do
    writeln(i,j)

Is there a one line for loop which swaps the i,j loops, i.e., it should do

for j in D.dim(1) do
  for i in D.dim(0) do
    writeln(i,j)

Hi @cpraveen

I'm not aware of a shorthand way to do so currently, but it should not be too hard to write a utility iterator to do this. For example, for the serial, 2D case, it should be as simple as:

iter colsFirst(D) {
  for j in D.dim(1) {
    for i in D.dim(0) {
      yield (i,j);
    }
  }
}

for ij in colsFirst({1..3, 1..4}) do
  writeln(ij);

[ATO]

For nD and parallel iterators, a bit more work would be involved (but maybe there's also not much motivation for a parallel iterator that swaps dimension orders since parallel iterators don't yield in a specified order?)

-Brad

1 Like

Thanks. I need it for serial loop only. When writing files for vtk/tecplot, they need opposite order.

I want to be able to write a output function which works for both 2d and 3d arrays, hence I was asking to find if such a thing already exists. Something like

for ij in reverse(D) do

which reverses the order of loops would be useful in some cases.

Welcome to Chapel's Discourse, @cpraveen!

In terms of adding something to the standard library, I wonder if adding a method to reverse a tuple would be a good idea for more general applicability. Here's a solution with tupleReverse:

var D2 = {1..#2, 2..#2};
var D3 = {1..#2, 2..#2, 3..#2};
var D4 = {1..#2, 2..#2, 3..#2, 4..#2};

proc tupleReverse(t) {
  param rank = t.size;  // TODO check tuple

  var revTup: rank*t[0].type;  // TODO check homogeneity?
  for param r in 0..<rank do
    revTup[r] = t(rank-r-1);

  return revTup;
}

iter reverseDims(Dom: domain(?)) {
  for revIdx in {(...tupleReverse(Dom.dims()))} do
    yield tupleReverse(revIdx);
}

writeln("D2");
for i in reverseDims(D2) do write(i);
writeln();

writeln("D3");
for i in reverseDims(D3) do write(i);
writeln();

writeln("D4");
for i in reverseDims(D4) do write(i);
writeln();

Edited to remove a thought based on a false assumption.