2016-03-13 10 views
0

советуюсь "Handle классы" разделHandle классы с 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 «s. (store - класс ручки).

Петля отлично работает с for; переключиться на parfor и store Состояние объекта не обновляется.

Это проблема с документом Matlab или с его пониманием?

UPD. Редактирование комментариев - это боль, поэтому я продолжаю здесь. Вот класс игрушек с двумя методами, изменяющий состояние объекта.

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) 

(А, В) оставить состояние без изменений, (C, D) работает надлежащим образом/рекламировали. Теперь мое «реальное», «не-игрушечное» состояние объектов представляет собой сочетание встроенных и пользовательских классов. (Элемент состояния, который не обновляется, представляет собой массив ячеек числовых массивов). Интересно, виноваты ли последние?

UPD2. Определенный пользователем класс дескриптора как свойство - все еще работает как ожидалось.

%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 работал нормально. Я останавливаюсь, пока не смогу придумать воспроизводимый пример.

+0

Где пример E? – Daniel

+0

Извинения, это была опечатка. –

+0

Хорошо, теперь все ведет себя так, как я ожидал. Я не знаю, почему ваш фактический код не работает. – Daniel

ответ

1

Это немного сложнее, так как мы не видим весь код, но моя догадка, что dosomething метод делает не возвращает экземпляр объекта модифицирована store и возвращает что-то другое вместо. Когда вы запускаете его с помощью обычного цикла for, этот метод фактически изменяет объект дескриптора . Однако, когда вы запускаете его с parfor, единственное, что остается за пределами цикла, - это возвращаемое значение dosomething, которое назначено stores(j). Пожалуйста, попробуйте следующее вместо:

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 возвращает сам объект, т.е.

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

Спасибо. Мой код фактически следовал второму шаблону, т. Е. Первая строка 'dosomething' была' function [obj] = dosomething (obj, data) ', но раньше я попробовал первый, более естественный шаблон. (У меня возникает соблазн попробовать что-то вроде 'stores (j) = 42', чтобы продемонстрировать, что объекты' store' никак не изменяются внутри цикла 'parfor'. Я надеюсь вернуться к этой теме с воспроизводимым примером игрушек, но опыт пока не обнадеживает, и похоже, что «parfor» Matlab - это не то, чем он взломал. –

0

Проблема решена, и она лежала за пределами представленного кода.

Петля parfor была внутри функции, simulateoneday, которая была вызвана в цикле от функции simulatemultipledays. simulatemultipledays перейдет на simulateoneday массив из store объектов, которые затем перейдут на parfor.

Это не было parfor, что было «сбросом» состояния объектов - вместо этого это был номер simulatemultipledays -to- simulateoneday. Когда я «поглотил» simulateoneday в simulatemultipledays, все начало работать.

Я задавался вопросом, не сработал ли я на pass-by-value-vs.-pass-by-reference, но, эй, код работал нормально с for - это было parfor, которое сломало вещи.

 Смежные вопросы

  • Нет связанных вопросов^_^