Matlab parfor error with biograph object: Struct contents reference from a non-struct array object
1 view (last 30 days)
Show older comments
Gabriel Otero
on 8 Jan 2019
Edited: Gabriel Otero
on 21 Jan 2019
Hi everyone,
I am struggling with a simple matlab parfor. I am using a biograph object representing a graph of interest. Since I have to compute a lot of shortest paths and the number of nodes is big, I thought it would be nice to use a parfor to speed up the computations. The code is as simple as this:
For the sake of the example, assume that we want to compute the shortest path from nodes 1, 2 and 3 to node 2.
cm = [0 1 1 0 0;1 0 0 1 1;1 0 0 0 0;0 0 0 0 1;1 0 1 0 0];
ids = {'M30931','L07625','K03454','M27323','M15390'};
bg = biograph(cm,ids);
workers = 3;
parpool('local', workers)
parfor i=1:3
[dist, pth, ~] = bg.shortestpath(i, 2);
end
The following error arises:
Struct contents reference from a non-struct array object.
I've already tried to call "bg.shortestpath(i, 2);" as a function but that didn't work. Maybe it has to do with the fact that biograph objects are treated like pointers by Matlab, meaning that if you execute,
bg2 = bg
, and then you modify any of the bg2's parameters, the changes are also reflected in bg.
I am aware that I could compute "bg.allshortestpaths" outside the loop and then extract the shortest path distance from there inside the loop but then, the path itself would remain unavailable.
I've read some related questions about this error but I don't know exactly how those relate with my biograph object data structure. I am sorry if this is a duplicate question but I am not keen on the Parallel Computing Toolbox and I feel very overwhelmed about how to approach this error. Maybe someone could point me in the right direction.
I am using MatlabR2017b.
Thank you in advance for the time you take in giving me some advice.
Regards,
Gabriel
2 Comments
Siddharth Bhutiya
on 16 Jan 2019
It seems to be something related to accessing the biograph object inside a parfor. What you can try is wrap it around a table object and then use it as follows
bg = biograph(cm,ids);
bgt = table(bg);
parfor i=1:3
[dist, pth, ~] = bgt.bg.shortestpath(i, 2);
end
Accepted Answer
More Answers (1)
Walter Roberson
on 16 Jan 2019
You might need to use parfevalOnAll to create the object on all of the workers.
I can tell from the existence of set() in https://www.mathworks.com/help/bioinfo/ref/biographobject.html that biograph likely derives from handle class. As such there is only one "official" object that can be referenced under many names. That conflicts with parfor as parfor uses distinct address spaces: if you were to set() inside one of the workers then the change would have to affect all the references, but cannot in parfor because those other references are in a different process.
Using parfevalOnAll would create different instances on the different workers, and using set() on one of them would only affect that one worker.
See Also
Categories
Find more on Parallel for-Loops (parfor) 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!