我有一个函数(卷积),如果它运行在许多列的矩阵上(下面的函数代码),它会变得非常慢。因此,我希望并行化代码。
示例MATLAB代码:
x = zeros(1,100);
x(rand(1,100)>0.8) = 1;
x = x(:);
c = convContinuous(1:100,x,@(t,p)p(1)*exp(-(t-p(2)).*(t-p(2))./(2*p(3).*p(3))),[1,0,3],false)
plot(1:100,x,1:100,c)
如果x
是多列的矩阵,则代码变得很慢......我的第一次尝试是将for
更改为parfor
语句,但它出错了(请参阅< em>下面的结束语。
我的第二次尝试是关注this example,其中显示了如何在作业中安排任务,然后将作业提交到本地服务器。通过让最后一个参数isParallel
为true
在我的函数中实现该示例。
示例MATLAB代码为:
x = zeros(1,100);
x(rand(1,100)>0.8) = 1;
x = x(:);
c = convContinuous(1:100,x,@(t,p)p(1)*exp(-(t-p(2)).*(t-p(2))./(2*p(3).*p(3))),[1,0,3],true)
现在,MATLAB告诉我:
使用&#39; local&#39;启动并行池(parpool)简介...连接到4名工人。
警告:此作业将保持排队,直到并行池关闭。
MATLAB终端保持等待完成任务。然后我按Jobs Monitor
打开Home -> Parallel -> Monitor jobs
,看到有两个作业,其中一个作业状态为running
。但是他们都没有完成。
问题
为什么跑的时间太长,因为这是一项非常简单的任务?
下面将我的功能并行化的最佳方法是什么? (&#34;重&#34;部分位于分离的函数convolveSeries
)
档案convContinuous.m
function res = convContinuous(tData, sData, smoothFun, par, isParallel)
% performs the convolution of a series of delta with a smooth function of parameters par
% tData = temporal space
% sData = matrix of delta series (each column is a different series that will be convolved with smoothFunc)
% smoothFun = function used to convolve with each column of sData
% must be of the form smoothFun(t, par)
% par = parameters to smoothing function
if nargin < 5 || isempty(isParallel)
isParallel = false;
end
if isvector(sData)
[mm,nn] = size(sData);
sData = sData(:);
end
res = zeros(size(sData));
[ ~, n ] = size(sData);
if ~isParallel
%parfor i = 1:n % uncomment this and comment line below for strange error
for i = 1:n
res(:,i) = convolveSeries(tData, sData(:,i), smoothFun, par);
end
else
myPool = gcp; % creates parallel pool if needed
sched = parcluster; % creates scheduler
job = createJob(sched);
task = cell(1,n);
for i = 1:n
task{i} = createTask(job, @convolveSeries, 1, {tData, sData(:,i), smoothFun, par});
end
submit(job);
wait(job);
jobRes = fetchOutputs(job);
for i = 1:n
res(:,i) = jobRes{i,1}(:);
end
delete(job);
end
if isvector(sData)
res = reshape(res, mm, nn);
end
end
function r = convolveSeries(tData, s, smoothFun, par)
r = zeros(size(s));
tSpk = s == 1;
j = 1;
for t = tData
for tt = tData(tSpk)
if (tt > t)
break;
end
r(j) = r(j) + smoothFun(t - tt, par);
end
j = j + 1;
end
end
结束语
作为旁注,我无法使用parfor
执行此操作,因为MATLAB R2015a
给了我一个奇怪的错误:
使用matlabpool时出错(第27行) matlabpool已被删除。
要查询已启动的并行池的大小,请查询“NumWorkers”&#39;游泳池的财产。
要检查池是否已启动,请使用&#39; isempty(gcp(&#39; nocreate&#39;))&#39;。
parallel_function出错(第317行) Nworkers = matlabpool(&#39; size&#39;);
convC连续出错(第18行) parfor i = 1:n
我的version
命令输出
Parallel Computing Toolbox Version 6.6 (R2015a)
与我的MATLAB版本兼容。差不多all other tests我做的还可以。然后我被迫认为这是一个MATLAB错误。
我尝试将matlabpool
更改为gcp
,然后按parPoolObj.NumWorkers
检索工作人员数量,在更改了两个不同内置函数中的详细信息后,我收到了另一个错误:< / p>
convContinuous中的错误&gt; makeF%1 / F%(第1行)
function res = convContinuous(tData,sData,smoothFun,par)
输出参数&#34; res&#34; (也许是其他人)在致电&#34; convContinuous&gt; makeF%1 / F%&#34;时未分配。
parallel_function中的错误&gt; iParFun(第383行) output.data = processInfo.fun(input.base,input.limit,input.data);
parProcess中的错误(第167行) data = processFunc(processInfo,data);
parallel_function出错(第358行) stateInfo = parProcess(@ iParFun,@ iConsume,@ iSupply,...
convC连接错误(第14行) parfor i = 1:numel(sData(1,:))
我怀疑最后一个错误是因为parfor
循环中的函数调用需要很多参数而产生的,但我真的不知道它。
解决错误
感谢此处人们的谨慎评论(说他们无法重现我的错误),我继续寻找错误的来源。我意识到由于pforfun
pathdef.m
pforfun
pathdef.m
parfor
而导致本地错误。
从我的convContinuous
移除{{1}}后,{{1}}({1}}功能中的第18行)开始运作良好。
提前谢谢!
答案 0 :(得分:3)
您创建的并行池阻止您的作业运行。当您使用作业和任务API时,您不需要(也不能有)池打开。当您查看Job Monitor时,您看到的正在运行的作业是支持并行池的作业,只有在删除池时才会完成。
如果您删除convContinuous
中标有myPool = gcp
的行,那么它应该有效。作为优化,您可以使用createTask的矢量化形式,这比在循环中创建任务更有效,即
inputCell = cell(1, n);
for i = 1:n
inputCell{i} = {tData, sData(:,i), smoothFun, par};
end
task = createTask(job, @convolveSeries, 1, inputCell);
然而,说了这么多,你应该能够使用parfor使这个代码工作。您遇到的第一个错误是由于matlabpool
被删除,现在已被parpool
取代。
第二个错误似乎是由于您的函数没有返回正确的输出,但错误消息似乎与您发布的代码不对应,所以我不确定。具体来说,我不知道convContinuous>makeF%1/F% (line 1)
指的是什么。
答案 1 :(得分:0)
感谢此处人们的谨慎评论(说他们无法重现我的错误),我继续寻找错误的来源。我意识到由于pforfun
pathdef.m
pforfun
pathdef.m
parfor
而导致本地错误。
从我的convContinuous
移除{{1}}后,{{1}}({1}}功能中的第18行)开始运作良好。