parfor and handle classes

2020-06-17 06:51发布

问题:

I have a handle class:

classdef A<handle


    properties
        a;
    end

    methods
        function obj = A(a)
            obj.a=a;
        end
    end
end

And I have a cell array of A objects:

arr={};
for i=1:3
    arr{i}=A(i);
end

What I would like to do is pass that cell array to a parfor loop so that each object's value will change:

parfor i=1:3
    arr{i}.a=i*5;
end

However, this code does not change arr at all. Indeed, here it states that

Changes made to handle classes on the workers during loop iterations are not automatically propagated to the client.

How can I overcome this?

回答1:

An interesting question; I actually never encountered this problem. It's always good to know everything about parfor limitations, so I did some googlin' and came up with this:

I have received an answer to this issue from technical support. Apparently the Mathworks regard it as a 'feature' that changes to objects are not returned - though I can't see that it's a very useful feature. Anyway, the way to get modified class properties returned from a parfor loop is to make an explicit change which can be recognised by parfor. Here are two examples which work for the above example object:

parfor n = 1:num
    exArray(n).data = n:n+5;
end

or

parfor n = 1:num
    temp = exArray(n);
    setData(temp,n:n+5);
    exArray(n) = temp;
end

Actually, if you change any object property it also seems to work. So for example this also works, if there is a second property data2 which is set explicitly, both data and data2 are correctly returned:

  parfor n = 1:num
      setData(exArray(n),n:n+5);
      exArray(n).data2 = n:n+5;
  end

Where the example object is given by

classdef Example < handle

    properties
        data
    end

    methods
        function obj = Example(data)
            obj.data = data;
        end

        function setData(obj,data)
            obj.data = data;
        end

        function data = getData(obj)
            data = obj.data;
        end
    end
end

and the array is initialized simply as

% Initialise array of objects
for n = 1:num
    exArray(n) = Example(zeros(1,6));
end