How to use properly parfor?

3 次查看(过去 30 天)
Mark Golberg
Mark Golberg 2016-2-23
Hello, I'm try to use "parfor" in order to execute 2 parallel actions: write frames to buffer & read frames from buffer.
My code is as follows:
parpool('local',4);
parfor i=1:2
[s,f] = bufferFUNC(i,vid,fps);
end
vid is my videoinput object. fps is the predefined FrameRate.
my bufferFUNC is as follows:
function [s,f] = bufferFUNC(i,vid,fps)
global bufferFrames
if i == 1 % read data from buffer
[pos,~,~,~] = Frames2Sound(bufferFrames,fps,'FALSE','FALSE','TRUE','FALSE');
[s , f , ~] = spectrogram(pos(1,:),kaiser(64,7), 62 , 64 , fps);
end
if i == 2 % write data into buffer
start(vid);
wait(vid);
frames = peekdata(vid, get(vid,'FramesAvailable'));
bufferFrames = squeeze(frames);
end
end
For some reason, when running in parfor configuration, I receive the following error:
Error using bufferFUNC (line 11)
An UndefinedFunction error was thrown on the workers for 'start'. This might be because the file containing 'start' is not
accessible on the workers. Use addAttachedFiles(pool, files) to specify the required files to be attached. See the
documentation for 'parallel.Pool/addAttachedFiles' for more details.
Caused by:
Undefined function 'start' for input arguments of type 'struct'.
Any idea why this is happening? If I ran the same script but with regular for then no problem... Why the fact that I'm using parfor causing MATLAB not to recognize the function "start"???
THANKS

回答(1 个)

Edric Ellis
Edric Ellis 2016-2-25
I think you need to create vid on the workers, I suspect the object does not correctly transfer from the client to the workers because they are separate MATLAB processes. You could try doing something like:
parfor idx = 1:4
vid = videoinput(...);
% use 'vid'
delete(vid);
end
If that works, you can use parallel.pool.Constant (or WorkerObjWrapper if you're not using R2015b), something like this:
vidWrapper = parallel.pool.Constant(@() videoinput(...), @delete);
parfor idx = 1:2
vid = vidWrapper.Value;
% use 'vid'
end
% Note that when 'vidWrapper' goes out of scope, 'delete' will be invoked
% on the object that was created.
  3 个评论
Walter Roberson
Walter Roberson 2016-2-25
global are not transferred between workers
Edric Ellis
Edric Ellis 2016-2-26
Ah, thanks @Walter, I hadn't spotted the use of global in there too - yes, global data is not synchronised.
If you need communication between the workers, you need to look into spmd blocks rather than parfor, and use labSend and labReceive to transfer data.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Startup and Shutdown 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by