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