Retrieve results preprocessed by a passed functor (parfor)

9 views (last 30 days)
Hello there, I'm desperately trying to retrieve results from simulations distributed to worker threads by means of "parfor". I'm trying to distribute a parameter-sweep, passing in a preparation function handle and a collector handle object. The latter is supposed to look at the generic results, calculate interesting values and then store them for the sweep caller. So it is kind of a functional design, to keep the simulation config and stuff away from the experiment code.
Following is the respective method in my Model-Abstraction-Class:
function run_sim_sweep( self, duration, omega_path, torque_path, prepare_func, collector, start_i, end_i )
collector_slices = collector.make_slices( end_i - start_i + 1 );
parfor i = start_i : end_i
feval( prepare_func, self, i );
local_result = self.run_sim( duration, omega_path, torque_path );
collector_slices{i}.collect( self, i, local_result );
collector_slices{i}.hack2 = i;
end
collector.fold_slices( collector_slices );
end
end
While it worked great with the single collector in serial loops, I had to slice the collector into an array of collectors for Matlab not to bark at me. But it still doesn't work the way I imagine it to work.
Here's my diagnostics: The slice's collect method stores the index i in a property "hack" and the loop stores the index too in the property "hack2". After the loop finishes, "hack" contains "2" for every element of the collector_slices cell array, whereas "hack2" contains "1" for every element.
(both collector, and the collector_slice-class it slices into are handle classes)
Can you spot an obvious mistake I made?
Best regards, Michael
  5 Comments
jgg
jgg on 19 Feb 2016
You should provide an answer in the "Answer" section so other people can see how you resolved your problem.

Sign in to comment.

Accepted Answer

decimad
decimad on 20 Feb 2016
Alright,
I resolved the issue and as it often happens, the initial estimation of the cause was way off. There was no problem with the data-collecting code.
The real problem was that the run_sim_sweep-method-containing class instance will be serialized and then deserialized on every worker thread of the pool (save, load roundrip). By default, Matlab will not call the class constructor on load. Since I install property listeners in the constructor, the resulting object in the worker thread was not watching changes to its properties. This could be overcome by specifying the class attribute "classdef (ConstructOnLoad=true) ...", which makes Matlab call the class constructor with 0 arguments on load.

More Answers (0)

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!