对3名工人并行执行3个功能

时间:2016-06-11 05:12:51

标签: matlab parallel-processing

我有三个函数(qrcalczcalcpcalc),我想要并行运行三个唯一的输入集。这是我的尝试,但它不起作用:

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

出错

对于如何做到这一点有什么建议吗?

以下是不需要自定义功能的代码版本。因此,我将其替换为zerosmagicones

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

1 个答案:

答案 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)];