UndefinedFunction error was thrown on the workers for 'filedata'

37 views (last 30 days)
When trying to run the code below:
outfname = ["path\to\file"];
% Telling workers which files to access
poolobj = gcp;
addAttachedFiles(poolobj, {'testdata.mat'});
% Getting workers to each access the file
imgdata = load('testdata.mat');
parfor idx = 1:300
idxCopy = idx;
if strlength(string(idx)) == 1
idxCopy = strcat('00', string(idx));
elseif strlength(string(idx)) == 2
idxCopy = strcat('0', string(idx));
this_outfname = [outfname, idxCopy, ".jpg"];
join(this_outfname, "");
some_function(this_outfname, imgdata, idx);
where 'imgdata' is a struct with each row having data that is unique to it's associated image. That is, every element of the struct is variable. Comments are my understandings of what I'm trying to do.
Having been unable to find a working solution, this is the output that I am getting:
Warning: Files that have already been attached are being ignored. To see which files are attached see the
'AttachedFiles' property of the parallel pool.
ProcessPool with properties:
Connected: true
NumWorkers: 4
Cluster: local
AttachedFiles: path\to\file
AutoAddClientPath: true
IdleTimeout: 30 minutes (23 minutes remaining)
SpmdEnabled: true
Analyzing and transferring files to the workers ...done.
Error using try_exifwrite (line 15)
An UndefinedFunction error was thrown on the workers for 'imgdata'. This might be because the file containing
'imgdata' is not accessible on the workers. Use addAttachedFiles(pool, files) to specify the required files to be
attached. For more information, see the documentation for 'parallel.Pool/addAttachedFiles'.
Caused by:
Unrecognized function or variable 'imgdata'.
Thank you for any help!
  1 Comment
benvolio on 4 Jun 2020
Also, Walter Robinson proposed a solution to a very similar problem here: https://fr.mathworks.com/matlabcentral/answers/381495-how-to-access-variables-in-parfor-loop-addattachedfiles
As I understand it and in the context of the OP, he is suggesting to "load('testdata.mat')" without having it in the spmd block. I tried this but it did not resolve the issue.

Sign in to comment.

Answers (1)

Edric Ellis
Edric Ellis on 5 Jun 2020
I'm a little confused by your example code there - I think there must be more going on. In your code, the piece
imgdata = load('testdata.mat');
Means that imgdata is a Composite. You cannot pass a Composite into a parfor loop - that will result in an error. I think you might be able to fix things by doing this:
% make a Constant on the workers that holds the contents
% of testdata.mat:
imageConstant = parallel.pool.Constant(@() load('testdata.mat'));
% Use the Constant inside parfor:
parfor idx = 1:N
imgdata = imageConstant.Value;
% imgdata is now equivalent to the result of "load('testdata.mat')"
This uses parallel.pool.Constant to load the data into a variable on the workers.

Community Treasure Hunt

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

Start Hunting!