Chapel: Can you re-index a domain in place?

101 Views Asked by At

A great man once said, I have a matrix A. But this time she has a friend B. Like the Montagues and Capulets, they have different domains.

// A.domain is { 1..10, 1..10 }
// B.domain is { 0.. 9, 0.. 9 }

for ij in B.domain {
  if B[ij] <has a condition> {
    // poops
    A[ij] = B[ij];
  }
}

My guess is I need to reindex so that the B.domain is {1..10, 1..10}. Since B is an input, I get push back from the compiler. Any suggestions?

2

There are 2 best solutions below

0
On BEST ANSWER

There's a reindex array method to accomplish exactly this, and you can create a ref to the result to prevent creating a new array:

var Adom = {1..10,1..10},
    Bdom = {0..9, 0..9};

var A: [Adom] real,
    B: [Bdom] real;

// Set B to 1.0
B = 1;

// 0-based reference to A -- note that Bdom must be same shape as Adom
ref A0 = A.reindex(Bdom);

// Set all of A's values to B's values
for ij in B.domain {
  A0[ij] = B[ij];
}

// Confirm A is now 1.0 now
writeln(A);
2
On

compiler must object,
documentation is explicit and clear on this:

Note that querying an array's domain via the .domain method or the function argument query syntax does not result in a domain expression that can be reassigned. In particular, we cannot do:

VarArr.domain = {1..2*n};

In case the <has_a_condition> is non-intervening and without side-effects, a solution to the expressed will may use domain-operators similar to this pure, contiguous-domain, index translation:

forall ij in B.domain do {
   if <has_a_condition> {
      A[ ij(1) + A.domain.dims()(1).low,
         ij(2) + A.domain.dims()(2).low
         ] = B[ij];
   }
}