本文介绍了使用Matlab parfor循环处理类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我查阅

http://uk.mathworks. com/help/distcomp/objects-and-handles-in-parfor-loops.html

并写下:

parfor j = 1:length(stores)
    store = stores(j);
    dataj = somefunction(store.someproperty, data(data.store == store.id, :));
    stores(j) = store.dosomething(dataj);
end

其中dosomething修改store的状态. (store是一个句柄类).

where dosomething modifies store's state. (store is a handle class).

循环与for正常工作;切换到parfor,并且store对象的状态无法更新.

The loop works fine with for; switch to parfor, and store object's state fails to be updated.

这是Matlab文档还是我的理解问题?

Is this a problem with Matlab's doc, or with my understanding of it?

UPD.编辑评论很痛苦,因此我在这里继续.这是一个玩具类,有两种方法可以修改对象的状态.

UPD. Editing comments is a pain, so I continue here. Here's a toy class, with two methods, modifying the object's state.

classdef shop < handle
    properties
        stock = 10
    end
    methods
        function clearstock(obj)
           obj.stock = 0;
        end
        function[obj] = clearstock2(obj)
           obj.stock = 0;
        end
    end
  end

现在测试脚本:

n = 1;
shops = repmat(shop, n, 1);
sprintf('Stock before: %d', shops(1).stock)
% A
parfor i = 1:n
    shops(i).clearstock;
end
sprintf('Stock after: %d', shops(1).stock)
% B
shops = repmat(shop, n, 1);
parfor i = 1:n
    shops(i).clearstock2;
end
sprintf('Stock after: %d', shops(1).stock)
% C
shops = repmat(shop, n, 1);
parfor i = 1:n
    shop = shops(i);
    shop.clearstock;
    shops(i) = shop;
end
sprintf('Stock after: %d', shops(1).stock)
% D
shops = repmat(shop, n, 1);
parfor i = 1:n
    shop = shops(i);
    shop = shop.clearstock2;
    shops(i) = shop;
end
sprintf('Stock after: %d', shops(1).stock)

(A,B)保持状态不变,(C,D)按预期/通告的方式工作.现在,我的真实",非玩具"对象状态是内置类和自定义类的混合. (未更新的状态元素是数字数组的单元格数组).我想知道是后者的罪魁祸首吗?

(A,B) leave the state unchanged, (C,D) work as intended/advertised. Now, my 'real', 'non-toy' objects' state is a mix of built-in and custom classes. (The state element that is not being updated is a cell array of numeric arrays). Are the latter to blame, I wonder?

UPD2.用户定义的句柄类作为属性-仍按预期运行.

UPD2. A user-defined handle class as a property - still working as expected.

%MANAGER.M
classdef manager < handle
    properties
        name
        salary = 100000;
    end
    methods
        function[obj] = manager(name)
            obj.name = name;
        end
        function giveraise(obj)
            obj.salary = 200000;
        end
        function[obj] = giveraise2(obj)
            obj.salary = 300000;
        end
    end
end
%SHOP.M
classdef shop < handle
    properties
        stock = 10;
        manager = manager('John Doe');
    end
    methods
        function clearstock(obj)
            obj.stock = 0;
        end
        function[obj] = clearstock2(obj)
            obj.stock = 0;
        end
    end
end
clc
n = 1;
shops = repmat(shop, n, 1);
sprintf('Stock before: %d', shops(1).stock)
sprintf('Salary before: %d', shops(1).manager.salary)
% A2
parfor i = 1:n
    shops(i).clearstock;
    shops(i).manager.giveraise;
end
sprintf('Stock after: %d', shops(1).stock)
sprintf('Salary after: %d', shops(1).manager.salary)
% B2
shops = repmat(shop, n, 1);
parfor i = 1:n
    shop = shops(i);
    shop.clearstock;
    shop.manager.giveraise;
    shops(i) = shop;
end
sprintf('Stock after: %d', shops(1).stock)
sprintf('Salary after: %d', shops(1).manager.salary)
% C2
shops = repmat(shop, n, 1);
parfor i = 1:n
    shop = shops(i);
    shop.manager = shop.manager.giveraise2;
    shop = shop.clearstock2;
    shops(i) = shop;
end
sprintf('Stock after: %d', shops(1).stock)
sprintf('Salary after: %d', shops(1).manager.salary)

那是关于值的类吗?

UPD3.不,shop属性的用户定义值类工作正常.我停下来,直到我想出一个可重复的例子.

UPD3. No, a user-defined value class for shop property worked fine. I stop until I can come up with a reproducible example.

推荐答案

这有点棘手,因为我们看不到完整的代码,但是我最好的猜测是dosomething方法没有没有返回修改后的store对象实例,并返回其他内容.当您使用常规的for循环运行它时,此方法实际上会更改store句柄对象.但是,当您使用parfor运行它时,唯一在循环外持久存在的东西是分配给stores(j)dosomething返回值.请尝试以下操作:

It's a bit tricky since we don't see the whole code, but my best guess is that dosomething method does not return the modified store object instance, and returns something else instead. When you run it with the usual for loop, this method actually changes store handle object. When you run it with parfor, however, the only thing that gets persisted outside the loop is the return value of dosomething that is assigned to stores(j). Please try the following instead:

parfor j = 1:length(stores)
    store = stores(j);
    dataj = somefunction(store.someproperty, data(data.store == store.id, :));
    store.dosomething(dataj);
    stores(j) = store;
end

作为替代方法,请确保dosomething返回对象本身,即

As an alternative, make sure dosomething returns the object itself, i.e.

function obj = dosomething(obj, dataj)
    % ...
end

这篇关于使用Matlab parfor循环处理类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 14:50