Is it possible to create a grid of locales where the distribution is distributed?
If I run the following code:
use BlockDist;
config const dimension: int = 5;
const space = {0..#dimension, 0..#dimension};
const matrixBlock: domain(2) dmapped Block(boundingBox=space) = space;
var A : [matrixBlock] int;
[a in A] a = a.locale.id;
writeln(A);
on 4 locales, I get:
0 0 0 1 1
0 0 0 1 1
0 0 0 1 1
2 2 2 3 3
2 2 2 3 3
Is there one A.<function>
that returns a matrix (below)?
0 1
2 3
Or, is this what I have to implement?
source to share
The expression A.targetLocales()
gives you almost what you asked for, and perhaps something that you find even more useful: instead of the requested array, int
it gives you an array of target locales. Thus, it writeln(A.targetLocales())
prints a 2x2 locale array:
LOCALE0 LOCALE1
LOCALE2 LOCALE3
This procedure and others related to querying locations on arrays can be found in the domain and array operations section of the online documentation, under array type.
The expression A.targetLocales().id
should give you what you want, but due to years of unimplemented feature not (at least as of version 1.15 of the Chapel). In short, this queries each locale for its identifier and should result in an int array with the same size and shape as the target local array; however, because promotion does not save the form as intended, the form is lost if you do not save it. For example, this writeln(A.targetLocales.id)
results in:
0 1 2 3
but not:
0 1
2 3
However, you can assign such extended expressions to an array of the desired shape. Thus, one way to get your desired ints array today would be to write:
// declare an array whose domain is the same as that of A target locales
// and initialize the array using the IDs of A targetLocales array:
var IDs: [A.targetLocales().domain] int = A.targetLocales().id;
Finally, note that you can pass your own array of locales into the broadcast constructor Block () if you want to specify a specific set of target locales, instead of using the default set of target locales it has configured for you. For example, adding the following two lines:
const locGridSpace = {0..#numLocales, 0..0};
const locGrid: [locGridSpace] locale = [(i,j) in locGridSpace] Locales[i];
will create an array of locales numLocales x 1, which can then be passed to your Block () call as follows:
const matrixBlock: domain(2) dmapped Block(boundingBox=space,
targetLocales=locGrid) = space;
Alternatively, you can order some or all of the locales in a different form or order. The main limitation is that the rank of the targetLocales array is the same as the rank of the targetLocales array, which refers to the domains to which the distribution is applied. (So ​​targetLocales should be 2D when distributing 2D domains and arrays, and 3D for 3D domains and arrays).
source to share
Arrays, domains and distributions have a method targetLocales()
that returns an array of locales over which the array / domain / distribution is distributed. See: Domain and Array Documentation .
The next calls:
writeln(A.targetLocales());
writeln(A.domain.targetLocales());
writeln(A.domain.dist.targetLocales());
All will be printed:
LOCALE0 LOCALE1
LOCALE2 LOCALE3
To extract the integral identifiers, you can use .id
accessor:
var targetLocs = A.targetLocales();
var targetLocIDs: [targetLocs.domain] int = targetLocs.id;
writeln(targetLocIDs);
Printing
0 1
2 3
source to share