Используя GOP, чтобы достигнуть функциональности MPI_Allreduce

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

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

Связанная документация:

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

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 оператор, представлены на клиенте как Составной объект. Мы можем принести получившиеся значения от лабораторий до клиента путем индексации в Составной объект во многом как тот из массивов ячеек:

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, являющейся сокращением от Глобальной Операции. Функция 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 и операции "исключающее ИЛИ" представлены @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 и операции "исключающее ИЛИ". Они представлены @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

Мы должны сделать только определенное программирование, чтобы найти labindex соответствие туда, где поэлементно максимум 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

Точно так же нам только нужны несколько строк кода, чтобы найти labindex, где поэлементно минимум 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