JJ Yeo
JJ Yeo

Reputation: 73

Parallel Programming on MATLAB to execute 3 different functions at the same time

I am writing a molecular dynamics code which requires the calculation of 3 different types of forces using 3 functions, namely Compute2BodyForce, Compute3BodyForce, and ComputeOtherForce. Since the functions are independant of each other and I want to calculate each function separately on 3 different cores, is the correct way of doing this be as below:

funList = {@Compute2BodyForce,@Compute3BodyForce,@ComputeOtherForce};

dataList = {data1,data2,data3}; %# or pass file names 

parfor i=1:length(funList)

    %# call the function

    funList{i}(dataList{i});

end

Secondly, how do I consolidate the results and sum them together, namely to get TotalForce = 2BodyForce + 3BodyForce + OtherForce?

Upvotes: 3

Views: 3051

Answers (1)

Sevenless
Sevenless

Reputation: 2835

You're on the right track. But, to my knowledge, you can't use anonymous functions in parfor (if I'm wrong or this was true only in an earlier version my apologies). Also you need to have a line in which you open your matlab pool and inform the worker nodes of what you intend to use within the parallel section. This is how I would start on this problem:

fileDep = {'Compute2BodyForce',...
'Compute3BodyForce',...
'ComputeOtherForce'};     

num_procs = 3;

matlabpool('open','Mycluster',num_procs,'FileDependencies',fileDep);

parfor iter = 1:3

% iter is passed to the functions so the functions can return NaNs when we don't want computation done
   body_2_dummy{iter} = Compute2BodyForce(data,iter); %assuming data is a variable here, maybe a struct that gets parsed inside the functions

   body_3_dummy{iter} = Compute3BodyForce(data,iter);

   other_dummy{iter} = ComputeOtherForce(data,iter);

end

% resolve and sum up here

total_force = body_2_dummy{1} + body_3_dummy{2} + other_dummy{3};

Note here that except for body_2_dummy{1}, body_3_dummy{2} and other_dummy{3} the values of these functions should return NaNs. This gets around a frustrating thing in Matlab. The typical way in most languages to code this would be something like:

parfor iter = 1:3
   if iter == 1
      body_2_dummy = Compute2Body(data);
   end
% more ifs for the other forces
end

Here it would be our responsibility to ensure that body_2_dummy has an unambiguous value. But in Matlab, this responsibility falls to the interpreter, and it doesn't allow this because it sees body_2_dummy as depending on the order of execution.

I hope this gets you on the right path. Feel free to come back with any further questions.

Also, as a general note of advice, it's usually significantly easier to optimize a function and try to reduce it's cost than to parallelize functions. Have you spent time with the force functions in the Matlab profiler?

--Andrew

Followup edits:

Anonymous functions are when you do something like this:

spam = @(x) x + 2;

spam(2)

   ans = 4

Here, spam is an anonymous function. You can pass the function to another function by passing the function handle which is @spam.

My experience with parallel computing toolbox is predominantly in conjunction with Sbiotoolbox. In this toolbox, biological models are objects and can be passed by handle reference in a way that's based on an older version of Matlab's handle graphics. The problem though is that the handle gets dissociated from the model and a series of rather confusing errors occurs. For this reason I avoid all reference by handle when using the parallel functionality of Matlab.

I must however admit that I've not tested if anonymous functions are usable as there's some further details around local vs. remote Matlab workers to give a rigorous answer. At the moment I don't have easy access to a remote Matlab cluster so this has to be put on the project list.

The Matlab profiler is a tool that comes with Matlab. It allows you to put in a function and measure the time spent in every line of code so you can highlight were you need to restructure the code to be faster. It's especially good at finding errors like arrays changing size in loops that eat up Matlab's performance.

I would encourage you to search for 'profiler' in the Matlab help. The documentation is pretty good and is much more complete than anything I could put here.

Best of luck.

Upvotes: 2

Related Questions