1
votes

I have a system that relies on an event, and to speed up the system I tried to parallelize it, however events don't seem to trigger in parallel loops. Since my system is too large I have it boiled down into about 30 lines here (3 files)

classdef eventsend < handle
    events
        go
    end
    methods
        function sendit(self)
            notify(self,'go');
        end
    end
end

classdef eventcatch
    methods
        function self = eventcatch(sender)
            addlistener(sender,'go',@self.doSomething);
        end
        function doSomething(varargin)
            disp('HERE');
        end
    end
end

function bug
    send = eventsend();
    eventcatch(send);
    a = @send.sendit;
    a();
    parfor i=1:5
        a();
    end
end

This will print HERE once, but if the par is removed it will work and print 6 times.

Question: Is there a way I can parallelize it and still have events?

1

1 Answers

3
votes

Let's review what happens when a parfor loop gets executed on a pool of local or remote workers:

(0) A separate Matlab instance spawns for each worker.

(1) The variables from the function workspace that are needed inside the loop are written to disk (if the parfor loop runs locally, they aren't actually written to disk, but for all practical purposes, it will appear as if they were). If parfor runs remotely, all .m-files get sent to the remote worker as well.

(2) Each Matlab instance loads the variables associated with the iteration they're supposed to evaluate, and runs the body of the parfor loop.

Your problem stems from either the fact that events cannot be passed between Matlab instances, or that you do not construct eventsent/eventcatch on load, which means that they aren't properly listening anymore.

In general, I find it easier to wrap parfor loops around classes, rather than within methods, so that I do not have to worry about funny side-effects of saving/loading objects.