我有三个函数(qrcalc
,zcalc
,pcalc
),我想要并行运行三个唯一的输入集。这是我的尝试,但它不起作用:
function [outall]=parallelfunc(in1,in2,in3)
if parpool('size') == 0 % checking to see if pool is already open
A=feature('numCores');
parpool('local',A);
else
parpool close
A=feature('numCores');
parpool('local',A);
end
spmd
if labindex==2
out1=qrcalc(in1);
elseif labindex==3
out2=zcalc(in2);
elseif labindex==4
out3=pcalc(in3);
end
outall=[out1;out2;out3];
end
错误:使用parallelattempt时出错>(spmd body)(第20行)错误 在worker 3上检测到一个UndefinedFunction错误 'out1'的工人。这可能是因为包含'out1'的文件是 工人无法进入。为此指定所需的文件 并行池使用命令:addAttachedFiles(pool,...)。见 有关parpool的文档以获取更多详细信息。
parallelattempt>(spmd)(第11行)spmd
出错parallelattempt(第11行)spmd
出错
对于如何做到这一点有什么建议吗?
以下是不需要自定义功能的代码版本。因此,我将其替换为zeros
,magic
和ones
:
function [outall]=parallelattempt(in1,in2,in3)
poolobj = gcp;
addAttachedFiles(poolobj,{'zeros.m','ones.m','magic.m'})
spmd
if labindex==2
out1=zeros(in1);
elseif labindex==3
out2=magic(in2);
elseif labindex==4
out3=ones(in3);
end
outall=[out1;out2;out3];
end
答案 0 :(得分:1)
如果使用spmd
- 语句,则会将内部代码发送给所有工作人员。通过使用labindex
,您只能在一个特定工作者上创建变量outX
。问题是,outall=[out1;out2;out3];
现在应该在没有声明两个outX
- 变量的工人上执行。对此错误的直接修复是在spmd
- 语句(out1=[]; out2=[]; out3=[];
)之前声明变量。但这不是最佳解决方案。
您可以在spmd
- 语句中使用单个变量而不是几个变量(outX
),让我们调用此变量out
。现在代码在每个worker上执行,并将其结果存储在out
中,这是一个Composite
- 对象。连接不是必需的,因为它是自动完成的。此外,您可以在块的开头指定spmd (3)
,只应使用3名工作人员。 Composite
- 对象可以像单元格数组一样被索引,其中索引等于worker / lab的数量。因此我们可以在块之后连接它。
这是该部分的具体代码:
spmd (3)
if labindex==1
out = qrcalc(in1);
elseif labindex==2
out = zcalc(in2);
elseif labindex==3
out = pcalc(in3);
end
end
outall = [out{1};out{2};out{3}];
请注意,如果不存在,池的创建将自动完成。您可能需要在声明之前附加函数的文件。
我认为更好的方法是在这里使用 parfeval
。这完全符合您想要实现的目标 - 它解决了您的初始问题。 outX
变量并行计算(非阻塞)。使用函数fetchOutputs
,您可以阻止执行,直到计算结果。在所有outX
- 变量上使用它并在同一行中连接它。
以下是代码:
out1 = parfeval(@qrcalc,1,in1);
out2 = parfeval(@zcalc,1,in2);
out3 = parfeval(@pcalc,1,in3);
outall = [fetchOutputs(out1);fetchOutputs(out2);fetchOutputs(out3)];