exponenta event banner

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

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

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 OPeration. 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

Поиск местоположений Мин и Макс

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