How to use properly parfor?

2 views (last 30 days)
Mark Golberg
Mark Golberg on 23 Feb 2016
Commented: Edric Ellis on 26 Feb 2016
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

Answers (1)

Edric Ellis
Edric Ellis on 25 Feb 2016
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 Comments
Edric Ellis
Edric Ellis on 26 Feb 2016
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.

Sign in to comment.

Categories

Find more on Startup and Shutdown in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!