在 parfor 循环中使用 Parsave - 只保存我的最后一个变量结果
Using Parsave inside parfor loop - saves only my last variable result
这是我的代码的简化版本。我想要获得的是 result.mat 中包含的 variable1 - 行向量。问题是 parsave - 仅保存一个结果,即第 10 次迭代的最后一个结果。我该怎么做才能将所有结果保存在 parfor 循环内的一个向量(在变量 1 中)中?
parfor ii = 1:10
[variable1, variable2] = MyFunction(~,~,ii);
parsave('result.mat',variable1, variable2)
end
function parsave(filename, varargin)
narginchk(2, Inf);
nargoutchk(0, 0);
for I = 2:nargin
varname = genvarname(inputname(I));
eval([varname ' = varargin{' num2str(I-1) '};'])
if (I == 2)
save(filename, varname)
else
save(filename, varname, '-append')
end
end
在 parsave
中,您有以下语句:
if (I == 2)
save(filename, varname)
else
save(filename, varname, '-append')
end
因此,在 parsave
的第一遍中,每次 运行 parsave
,都会覆盖 filename
.
此外,您的代码存在竞争条件的巨大风险:假设两个进程尝试同时执行文件的 "initial save" - 一个将覆盖另一个,或者抛出"cannot access file" 错误。
你最好在 parfor 循环中保存到临时文件,然后使用聚合器函数来跟进,该函数将不同的保存组合成有用的东西 - 或者每次你 运行 循环,而不是创建一个新文件。
上找到了一个优雅的解决方案
parpool('local',10); % results will be distributed on 10 workers
output1=distributed.NaN(1,1e5); %pre-allocate
output2=distributed.NaN(1,1e5);
spmd
for i=drange(1:1e5)
[output1(ii), output2(ii)] = MyFunction(~,~,ii);
parsave(['output1', num2str(labindex)],...
getLocalPart(output1));
parsave(['output2', num2str(labindex)],...
getLocalPart(output2));
end
end
我已经使用了 2 次 parsave 函数,以防机器在模拟结束前关闭,将保存 10 个 mat 文件以及我需要稍后连接的临时结果(用于输出 1 和输出 2)
parsave 函数是:
function parsave(fname,data)
var_name=genvarname(inputname(2));
eval([var_name '=data'])
try
save(fname,var_name,'-append')
catch
save(fname,var_name)
end
% Written by Minjie Xu (<mailto:chokkyvista06@gmail.com chokkyvista06@gmail.com>)
这是我的代码的简化版本。我想要获得的是 result.mat 中包含的 variable1 - 行向量。问题是 parsave - 仅保存一个结果,即第 10 次迭代的最后一个结果。我该怎么做才能将所有结果保存在 parfor 循环内的一个向量(在变量 1 中)中?
parfor ii = 1:10
[variable1, variable2] = MyFunction(~,~,ii);
parsave('result.mat',variable1, variable2)
end
function parsave(filename, varargin)
narginchk(2, Inf);
nargoutchk(0, 0);
for I = 2:nargin
varname = genvarname(inputname(I));
eval([varname ' = varargin{' num2str(I-1) '};'])
if (I == 2)
save(filename, varname)
else
save(filename, varname, '-append')
end
end
在 parsave
中,您有以下语句:
if (I == 2)
save(filename, varname)
else
save(filename, varname, '-append')
end
因此,在 parsave
的第一遍中,每次 运行 parsave
,都会覆盖 filename
.
此外,您的代码存在竞争条件的巨大风险:假设两个进程尝试同时执行文件的 "initial save" - 一个将覆盖另一个,或者抛出"cannot access file" 错误。
你最好在 parfor 循环中保存到临时文件,然后使用聚合器函数来跟进,该函数将不同的保存组合成有用的东西 - 或者每次你 运行 循环,而不是创建一个新文件。
parpool('local',10); % results will be distributed on 10 workers
output1=distributed.NaN(1,1e5); %pre-allocate
output2=distributed.NaN(1,1e5);
spmd
for i=drange(1:1e5)
[output1(ii), output2(ii)] = MyFunction(~,~,ii);
parsave(['output1', num2str(labindex)],...
getLocalPart(output1));
parsave(['output2', num2str(labindex)],...
getLocalPart(output2));
end
end
我已经使用了 2 次 parsave 函数,以防机器在模拟结束前关闭,将保存 10 个 mat 文件以及我需要稍后连接的临时结果(用于输出 1 和输出 2)
parsave 函数是:
function parsave(fname,data)
var_name=genvarname(inputname(2));
eval([var_name '=data'])
try
save(fname,var_name,'-append')
catch
save(fname,var_name)
end
% Written by Minjie Xu (<mailto:chokkyvista06@gmail.com chokkyvista06@gmail.com>)