在这个例子中,我们看共和党
函数及其构建的函数:gplus
和gcat
.这些看似简单的函数实际上是并行编程中非常强大的工具。
的共和党
函数允许我们对在所有实验中定义的变量执行任何联合二进制操作。这使得我们不仅可以在所有实验室中对变量进行求和,还可以在所有实验室中找到变量的最小值和最大值,并将它们连接起来,然后执行许多其他有用的操作。
相关文档:
spmd
在并行计算工具箱™用户指南中
在这个函数中可以找到这个例子中的代码:
函数paralleltutorial_gop
在进行并行编程时,我们经常会遇到这样的情况:在所有的实验室中都定义了一个变量,我们想要对这个变量进行操作,因为它在所有的实验室中都存在。例如,如果我们输入一个spmd语句并定义
spmdx = labindex;结束
在所有的实验室中,我们可能想要计算x
在实验室。这就是gplus
运算,它求和x
在所有实验室中复制结果:
spmds = gplus (x)公关;结束
在spmd语句中分配的变量在客户机上表示为Composite。我们可以将实验室的结果值通过索引到Composite中,就像单元格数组一样:
年代{1}%显示实验1中s的值。所有的实验室都保存相同的价值。
ans = 78
同时,共和党
,gplus
,gcat
允许我们指定函数输出应该返回到的单个实验室,它们会在其他实验室返回一个空向量。
spmdS = gplus(x, 1);结束年代{1}
ans = 78
这个示例展示了如何在所有实验室中执行与添加类似的一系列操作。在MPI中,这些操作被称为集合操作,如MPI_SUM、MPI_PROD、MPI_MIN、MPI_MAX等。
我们在所有示例中使用的数据非常简单:一个1乘2的变量数组,仅比x
我们在开始时定义:
spmdX = labindex + (1:2)结束
现在我们已经初始化了向量x
对于实验室中不同的值,我们可以问这样的问题,例如,每个元素的值的和是多少x
在实验室吗?那么乘积,最小值和最大值呢?正如我们的介绍所期望的那样,
spmds = gplus (x)公关;结束年代{1}
Ans = 90 102
的值逐个元素地返回x
.然而,gplus
只是……的特殊情况吗共和党
operation, Global operation的缩写。的共和党
函数允许我们跨实验室对变量数组的元素执行任何关联操作。关联运算最基本的例子是加法运算;它是关联的,因为加法独立于所使用的分组:
(a + b) + c = a + (b + c)
在MATLAB®中,加法可以用@plus
函数句柄,所以我们也可以写gplus (x)公关
作为
spmdS = gop(@plus, x);结束年代{1}
Ans = 90 102
我们可以连接这个向量x
通过使用gcat
函数,我们可以选择连接的维度。
spmdY1 = gcat(x, 1);沿行连接。Y2 = gcat(x, 2);%沿列连接。结束y1 y2 {1} {1}
ans = 2 3 3 4 5 4 5 6 6 7 7 8 9 9 8 10 10 11 11 12 12 13 13 14 ans = 1到13列2 3 3 4 4 5 6 5 6 7 7 8 8列14到24日9 9 10 10 11 11 12 12 13 13 14
的值的元素与元素的乘积计算起来很简单x
在实验室:
spmdP = gop(@times, x);结束p {1}
Ans = 1.0e+10 * 0.6227 4.3589
我们还可以逐元素求出的最大值x
在实验室:
spmdM = gop(@max, x);M = gop(@min, x);结束M {1} {1}
Ans = 13 14 Ans = 2 3
MATLAB甚至有更多内置的关联运算。属性表示逻辑与、或和异或操作@and
,@or
,@xor
函数处理。例如,查看逻辑数组
spmdY = (x > 4)结束
然后,我们可以轻松地对元素执行这些逻辑操作y
在实验室:
spmdYand = gop(@and, y);Yor = gop(@or, y);Yxor = gop(@xor, y);结束yand了{1}{1}yxor {1}
Ans = 1×2 logical array 0 0 Ans = 1×2 logical array 1 1 Ans = 1×2 logical array 1 0
为了结束我们在MATLAB中构建的关联运算之旅,我们看一下按位的与、或和异或运算。这些是用@bitand
,@bitor
,@bitxor
函数处理。
spmdXbitand = gop(@bitand, x);Xbitor = gop(@bitor, x);Xbitxor = gop(@bitxor, x);结束xbitand {1} xbitor {1} xbitxor {1}
Ans = 0 0 Ans = 15 15 Ans = 0 12
我们只需要做一点编程来找到对应于每个元素最大值的labindexx
整个实验室都发生了。我们只需要几行代码就可以做到:
类型pctdemo_aux_gop_maxloc
function [val, loc] = pctdemo_aux_gop_maxloc(inval) % pctdemo_aux_gop_maxloc查找变量的最大值及其labindex。% [val, loc] = pctdemo_aux_gop_maxloc(inval)返回val在所有实验室中inval的最大值%。这个最大值%所在的labindex返回给loc。% Copyright 2007 The MathWorks, Inc. out = gop(@iMaxLoc, {inval, labindex*ones(size(inval))});val = {1};loc = {2};end function out = iMaxLoc(in1, in2) %计算最大值及其位置。将它们作为单元格数组返回。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);结束maxloc [maxval {1}, {1})
Ans = 13 14 12 12
类似地,我们只需要几行代码就可以找到labindex,其中每个元素的最小值为x
整个实验室发生了:
类型pctdemo_aux_gop_minloc
function [val, loc] = pctdemo_aux_gop_minloc(inval) % pctdemo_aux_gop_minloc查找变量最小值及其labindex。% [val, loc] = pctdemo_aux_gop_minloc(inval)返回val在所有实验中的最小值% inval。这个最小值%所在的labindex返回给loc。% Copyright 2007 The MathWorks, Inc. out = gop(@iMinLoc, {inval, labindex*ones(size(inval))});val = {1};loc = {2};end function out = iMinLoc(in1, in2) %计算最小值及其位置。将它们作为单元格数组返回。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
我们可以很容易地找到最小值共和党
:
spmd[minval, minloc] = pctdemo_aux_gop_minloc(x);结束minloc [minval {1}, {1})
Ans = 2 3 1 1