问题描述
我查阅
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循环处理类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!