Использование GOP для достижения MPI_Allreduce функциональности

В этом примере мы рассмотрим gop функция и функции, которые на ней строятся: gplus и gcat. Эти, казалось бы, простые функции оказываются очень мощными инструментами при параллельном программировании.

The gop функция позволяет нам выполнить любую ассоциативную двоичную операцию для переменной, которая задана во всех лабораториях. Это позволяет нам не только суммировать переменную по всем лабораториям, но и найти ее минимум и максимум по лабораториям, объединить их и выполнить много других полезных операций.

Сопутствующая документация:

  • spmd в Руководстве пользователя Parallel Computing Toolbox™

Код, показанный в этом примере, можно найти в этой функции:

function paralleltutorial_gop

%#ok<*NOPRT>: disable code analyzer printing warning

Введение

При выполнении параллельного программирования мы часто сталкиваемся с ситуацией, когда переменная задана во всех лабораториях, и мы хотим выполнить операцию над переменной, поскольку она существует во всех лабораториях. Для примера, если мы вводим оператор spmd и задаем

spmd
    x = labindex
end
Lab  1: 
  
  x =
  
       1
  
Lab  2: 
  
  x =
  
       2
  
Lab  3: 
  
  x =
  
       3
  
Lab  4: 
  
  x =
  
       4
  
Lab  5: 
  
  x =
  
       5
  
Lab  6: 
  
  x =
  
       6
  
Lab  7: 
  
  x =
  
       7
  
Lab  8: 
  
  x =
  
       8
  
Lab  9: 
  
  x =
  
       9
  
Lab 10: 
  
  x =
  
      10
  
Lab 11: 
  
  x =
  
      11
  
Lab 12: 
  
  x =
  
      12
  

во всех лабораториях, мы, возможно, захотим вычислить сумму значений x через лаборатории. Это именно то, что gplus операция делает, она суммирует x в лабораториях и дублирует результат во всех лабораториях:

spmd
    s = gplus(x);
end

Переменные, назначенные в операторе spmd, представлены на клиенте как Composite. Получившиеся значения из лабораторий мы можем принести клиенту путем индексации в Composite, во многом подобной значению массивов ячеек:

s{1} % Display the value of s on lab 1.  All labs store the same value.
ans =

    78

Кроме того, gop, gplus, и gcat позволяет нам задать одну лабораторию, в которую должны быть возвращены выходы функции, и они возвращают пустой вектор в других лабораториях.

spmd
    s = gplus(x, 1);
end
s{1}
ans =

    78

В этом примере показано, как выполнить множество операций, аналогичных сложению во всех лабораториях. В MPI они известны как коллективные операции, такие как MPI_SUM, MPI_PROD, MPI_MIN, MPI_MAX и т.д.

Создайте входные данные для наших примеров

Данные, которые мы используем для всех наших примеров, очень просты: массив вариантов 1 на 2, который лишь немного сложнее x мы определили в начале:

spmd
    x = labindex + (1:2)
end
Lab  1: 
  
  x =
  
       2     3
  
Lab  2: 
  
  x =
  
       3     4
  
Lab  3: 
  
  x =
  
       4     5
  
Lab  4: 
  
  x =
  
       5     6
  
Lab  5: 
  
  x =
  
       6     7
  
Lab  6: 
  
  x =
  
       7     8
  
Lab  7: 
  
  x =
  
       8     9
  
Lab  8: 
  
  x =
  
       9    10
  
Lab  9: 
  
  x =
  
      10    11
  
Lab 10: 
  
  x =
  
      11    12
  
Lab 11: 
  
  x =
  
      12    13
  
Lab 12: 
  
  x =
  
      13    14
  

Использование GPLUS и GCAT

Теперь, когда мы инициализировали наш вектор x для различных значений в лабораториях, мы можем задать вопросы, например, какова поэлементная сумма значений x через лаборатории? Как насчет продукта, минимума и максимума? Как следует ожидать от нашего введения,

spmd
    s = gplus(x);
end
s{1}
ans =

    90   102

возвращает сложение значений x. Однако gplus является только частным случаем gop операция, сокращение от Global OPerement. The gop функция позволяет нам выполнить любую ассоциативную операцию через лаборатории на элементах массива варианта массива. Самый основной пример ассоциативной операции - сложение; он ассоциативен, поскольку сложение не зависит от используемой группировки:

(a + b) + c = a + (b + c)

В MATLAB ® сложение может быть обозначено @plus указатель на функцию, поэтому мы также можем записать gplus(x) как

spmd
    s = gop(@plus, x);
end
s{1}
ans =

    90   102

Мы можем конкатенировать вектор x через лаборатории при помощи gcat функция, и мы можем выбрать размерность, чтобы объединить вместе.

spmd
    y1 = gcat(x, 1); % Concatenate along rows.
    y2 = gcat(x, 2); % Concatenate along columns.
end
y1{1}
y2{1}
ans =

     2     3
     3     4
     4     5
     5     6
     6     7
     7     8
     8     9
     9    10
    10    11
    11    12
    12    13
    13    14


ans =

  Columns 1 through 13

     2     3     3     4     4     5     5     6     6     7     7     8     8

  Columns 14 through 24

     9     9    10    10    11    11    12    12    13    13    14

Другие элементарные виды использования GOP

Просто вычислить поэлементный продукт значений x через лаборатории:

spmd
    p = gop(@times, x);
end
p{1}
ans =

   1.0e+10 *

    0.6227    4.3589

Мы также можем найти элемент за элементом максимум x через лаборатории:

spmd
    M = gop(@max, x);
    m = gop(@min, x);
end
M{1}
m{1}
ans =

    13    14


ans =

     2     3

Логические операции

У MATLAB еще больше встроенных ассоциативных операций. Логические операции AND, OR и XOR представлены @and, @or, и @xor указатели на функцию. Например, посмотрите на логический массив

spmd
    y = (x > 4)
end
Lab  1: 
  
  y =
  
       0     0
  
Lab  2: 
  
  y =
  
       0     0
  
Lab  3: 
  
  y =
  
       0     1
  
Lab  4: 
  
  y =
  
       1     1
  
Lab  5: 
  
  y =
  
       1     1
  
Lab  6: 
  
  y =
  
       1     1
  
Lab  7: 
  
  y =
  
       1     1
  
Lab  8: 
  
  y =
  
       1     1
  
Lab  9: 
  
  y =
  
       1     1
  
Lab 10: 
  
  y =
  
       1     1
  
Lab 11: 
  
  y =
  
       1     1
  
Lab 12: 
  
  y =
  
       1     1
  

Затем мы можем легко выполнить эти логические операции над элементами y через лаборатории:

spmd
    yand = gop(@and, y);
    yor = gop(@or, y);
    yxor = gop(@xor, y);
end
yand{1}
yor{1}
yxor{1}
ans =

     0     0


ans =

     1     1


ans =

     1     0

Побитовые операции

Чтобы завершить наш тур по ассоциативным операциям, которые встроены в MATLAB, мы рассмотрим побитовые операции AND, OR и XOR. Они представлены @bitand, @bitor, и @bitxor указатели на функцию.

spmd
    xbitand = gop(@bitand, x);
    xbitor = gop(@bitor, x);
    xbitxor = gop(@bitxor,  x);
end
xbitand{1}
xbitor{1}
xbitxor{1}
ans =

     0     0


ans =

    15    15


ans =

     0    12

Поиск местоположений Min и Max

Нам нужно сделать всего лишь небольшой бит программирования, чтобы найти лабиндекс, соответствующий тому, где элемент за элементом максимум x через лаборатории происходит. Мы можем сделать это всего в нескольких строках кода:

type pctdemo_aux_gop_maxloc
function [val, loc] = pctdemo_aux_gop_maxloc(inval)
%PCTDEMO_AUX_GOP_MAXLOC Find maximum value of a variant and its labindex.
%   [val, loc] = pctdemo_aux_gop_maxloc(inval) returns to val the maximum value
%   of inval across all the labs.  The labindex where this maximum value
%   resides is returned to loc.

%   Copyright 2007 The MathWorks, Inc.

    out = gop(@iMaxLoc, {inval, labindex*ones(size(inval))});
    val = out{1};
    loc = out{2};
end

function out = iMaxLoc(in1, in2)
% Calculate the max values and their locations.  Return them as a cell array.
    in1Largest = (in1{1} >= in2{1});
    maxVal = in1{1};
    maxVal(~in1Largest) = in2{1}(~in1Largest);
    maxLoc = in1{2};
    maxLoc(~in1Largest) = in2{2}(~in1Largest);
    out = {maxVal, maxLoc};
end

и когда функция реализована, она может применяться так же легко, как и любая из встроенных операций:

spmd
    [maxval, maxloc] = pctdemo_aux_gop_maxloc(x);
end
[maxval{1}, maxloc{1}]
ans =

    13    14    12    12

Точно так же нам нужно только несколько строк кода, чтобы найти лабиндекс, где минимальное значение элемента за элементом x через лаборатории происходит:

type pctdemo_aux_gop_minloc
function [val, loc] = pctdemo_aux_gop_minloc(inval)
%PCTDEMO_AUX_GOP_MINLOC Find minimum value of a variant and its labindex.
%   [val, loc] = pctdemo_aux_gop_minloc(inval) returns to val the minimum value
%   of inval across all the labs.  The labindex where this minimum value
%   resides is returned to loc.

%   Copyright 2007 The MathWorks, Inc.

    out = gop(@iMinLoc, {inval, labindex*ones(size(inval))});
    val = out{1};
    loc = out{2};
end

function out = iMinLoc(in1, in2)
% Calculate the min values and their locations.  Return them as a cell array.
    in1Smallest = (in1{1} < in2{1});
    minVal = in1{1};
    minVal(~in1Smallest) = in2{1}(~in1Smallest);
    minLoc = in1{2};
    minLoc(~in1Smallest) = in2{2}(~in1Smallest);
    out = {minVal, minLoc};
end

Мы можем затем легко найти минимум с gop:

spmd
    [minval, minloc] = pctdemo_aux_gop_minloc(x);
end
[minval{1}, minloc{1}]
ans =

     2     3     1     1