Конкретные детали того, как индексы домена сопоставляются с локалями программы, определяются не самим языком Chapel, а скорее реализацией карты домена, используемой для объявления домена. В комментариях под вашим вопросом вы упоминаете, что имеете в виду дистрибутив Block
, поэтому я сосредоточусь на нем в своем ответе (задокументировано здесь), но обратите внимание, что для любой другой карты домена может использоваться другой подход.
Дистрибутив Block
принимает необязательный аргумент targetLocales
, который позволяет указать набор целевых языков, а также их виртуальную топологию. Например, если я объявлю и заполню несколько массивов локалей:
var grid1: [1..3, 1..2] locale, // a 3 x 2 array of locales
grid2: [1..2, 1..3] locale; // a 2 x 3 array of locales
for i in 1..3 {
for j in 1..2 {
grid1[i,j] = Locales[(2*(i-1) + j-1)%numLocales];
grid2[j,i] = Locales[(3*(j-1) + i-1)%numLocales];
}
}
Затем я могу передать их в качестве аргументов targetLocales
нескольким экземплярам Block
-распределенного домена:
use BlockDist;
config const n = 8;
const D = {1..n, 1..n},
D1 = D dmapped Block(D, targetLocales=grid1),
D2 = D dmapped Block(D, targetLocales=grid2);
Каждый домен будет распределять свои n
строк по первому измерению своей сетки targetLocales
и свои n
столбцов по второму измерению. Мы можем увидеть результаты этого распределения, объявив массивы целых чисел по этим доменам и назначив их параллельно, чтобы каждый элемент хранил идентификатор своей локали, как показано ниже:
var A1: [D1] int,
A2: [D2] int;
forall a in A1 do
a = here.id;
forall a in A2 do
a = here.id;
writeln(A1, "\n");
writeln(A2, "\n");
При работе с шестью или более локалями (./a.out -nl 6
) вывод выглядит следующим образом, раскрывая базовую структуру сетки:
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
2 2 2 2 3 3 3 3
2 2 2 2 3 3 3 3
2 2 2 2 3 3 3 3
4 4 4 4 5 5 5 5
4 4 4 4 5 5 5 5
0 0 0 1 1 1 2 2
0 0 0 1 1 1 2 2
0 0 0 1 1 1 2 2
0 0 0 1 1 1 2 2
3 3 3 4 4 4 5 5
3 3 3 4 4 4 5 5
3 3 3 4 4 4 5 5
3 3 3 4 4 4 5 5
Для одномерного массива targetLocales
в документации говорится:
Если ранг targetLocales
равен 1
, используется жадная эвристика для изменения формы массива целевых локалей, чтобы он соответствовал рангу распределения, и каждое измерение содержало примерно равное количество индексов.
Например, если мы распределяем по одномерному 4-элементному массиву локалей:
var grid3: [1..4] locale;
for i in 1..4 do
grid3[i] = Locales[(i-1)%numLocales];
var D3 = D dmapped Block(D, targetLocales=grid3);
var A3: [D3] int;
forall a in A3 do
a = here.id;
writeln(A3);
мы можем видеть, что целевые локали образуют квадрат, как и ожидалось:
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 1 1 1 1
2 2 2 2 3 3 3 3
2 2 2 2 3 3 3 3
2 2 2 2 3 3 3 3
2 2 2 2 3 3 3 3
Документация намеренно нечетко описывает, как будет изменена форма аргумента 1D targetLocales
, если он не является идеальным квадратом, но мы можем узнать, что делается на практике, используя targetLocales()
query в домене. Также обратите внимание, что если массив targetLocales
не указан, по умолчанию используется весь массив Locales
(который является 1D). В качестве иллюстрации обеих этих вещей, если следующий код запускается на шести локалях:
var D0 = D dmapped Block(D);
writeln(D0.targetLocales());
мы получаем:
LOCALE0 LOCALE1
LOCALE2 LOCALE3
LOCALE4 LOCALE5
иллюстрируя, что текущая эвристика соответствует нашему явному объявлению grid1
выше.
person
Brad
schedule
07.08.2017