Parallel processing queries - matlab

I have written a program in matlab and my algorithm depends on few parameters let's say a and b with a=1:10 and b=1:10 I want to find those values of a and b which gives me the best results.
My main code is as follows:
a= 0.1:0.1:1;
b= 1:1:10;
arr_mat = zeros(length(a),length(b));
for i=1:length(a)
for j=1:length(b)
disp(['loop no = ',num2str(i),' & ',num2str(j)]);
knn = a(j);
eta = b(i);
arr_mat(i,j) = called_function(knn,eta);
end
end
The program runs but is very computationally expensive. I was wondering if there is any matlab inbuilt parallel processing toolbox which will be helpful for me in this case. I was thinking along these lines :
Divide my main program into parts:
a1= 0.1:0.1:0.5;
b1= 1:1:5;
arr_mat1 = zeros(length(a1),length(b1));
for i1=1:length(a)
for j1=1:length(b)
disp(['loop no = ',num2str(i1),' & ',num2str(j1)]);
knn1 = a1(j);
eta1 = b1(i);
arr_mat1(i,j) = called_function(knn1,eta1);
end
end
a2= 0.6:0.1:1;
b2= 6:1:10;
arr_mat2 = zeros(length(a2),length(b2));
for i2=1:length(a2)
for j2=1:length(b2)
disp(['loop no = ',num2str(i2),' & ',num2str(j2)]);
knn2 = a2(j);
eta2 = b2(i);
arr_mat2(i,j) = called_function(knn2,eta2);
end
end
Run the codes in parallel. My system configuration is : Intel Core i7-3770 # 3.40 GHz with 32.0 GB RAM. I have MATLAB 2013b installed.
I have consulted this question and have tried to write my own code in that format:
clc;clear all;close all;
% run ixmas for different modifications
a= 0.1:0.1:1;
b= 1:1:10;
arr_mat = zeros(length(a),length(b));
matlabpool open local 2
parfor i=1:length(a)
for j=1:length(b)
disp(['loop no = ',num2str(i),' & ',num2str(j)]);
knn = a(j);
eta = b(i);
recog = 0;
for k=1:5
recog(k) = ixmas(knn,eta);
end
arr_mat(i,j) = mean(recog);
end
end
end
matlabpool close
This code throws up the error : "Illegal use of reserved keyword "end"."
My queries :
Kindly please tell me where I am going wrong.
I tried to introduce a parfor in the inner loop but it throws up an error?
What does the statement matlabpool open local 2 mean ?
How many threads can I use in parallel for my system configuration ? How can I even check those limits and optimally use them to the full capacity ?
Does parallel processing means utilizing different cores of my own machine or utilizing resources of other machines ? Is there any way either options can be selected and how does one go about doing so?

matlabpool does not open a statement that needs a closing end. In the linked question the end is closing the spmd statement.
The meaning of the statement matlabpool open local 2 is:
matlabpool open or closes a pool of matlab parallel processing worker processes.
open tells matlab to run these workers. (this is the default)
local tells matlab to open these workers on the local machine (this is the default)
2 tells matlab to run 2 such workers (default is number of cpus)
You can just matlabpool without any parameters.
in order to configure the local profile go to the matlab home tab and choose 'manage clusters' under the parallel menu.
Also, for some strange reason matlab can't split the array between the workers when the parfor is not in the inner most loop. change the inner for to parfor and it will work.

Related

Parallel Optimization with matlab fmincon

So I am trying to optimize 2 set parameters one for each axle of this scheme.The first set has to be optimized on delta between left and right flywheel, while set 2 is the same for the other axle
At the moment I am using fmincon and running in parallel the simulation of left and right flywheel of each axle as the cost function is the error between the two outputs.
The basic code is something like this
for Axle = 1:2
...
fmincon(CostFunc,InitialValues, lb,ub)
end
The CostFunc is something like this
fob = CostFunc(...)
parfor FlyWheel = 1:2
FlyWheelOutput(FlyWheel) = simulation(...)
end
fob = FlyWheelOutput(1) - FlyWheelOutput(2)
So instead of 4 cores I a using only 2, making the code slower than what it could ideally be. So the question is do you know anyway how to overcompe this impasse?
Basic scheme
If my understanding is correct, your code effectively has this basic structure:
for Axle = 1:2
...
% fmincon(Costfunc, ...)
parfor FlyWheel = 1:2
FlyWheelOutput(FlyWheel) = simulation(...)
end
% end fmincon
end
You could potentially speed up processing by moving parfor to the outer loop instead.
parfor Axle = 1:2
...
% fmincon(Costfunc, ...)
for FlyWheel = 1:2
FlyWheelOutput(FlyWheel) = simulation(...)
end
% end fmincon
end
While I can't guarantee that you will use all 4 CPU cores simultaneously instead of 2, this could be faster, since you are executing parfor once outside a loop, instead of twice inside a loop.
If runtime is still a problem, consider using the built-in profiling tool to find out which part of your code is slowest, then optimize from there.

Parallel execution of COM instances in Matlab

I'm trying to accelerate our test environment by using the ParralelToolbox of Mathworks. However I am unable to start several Matlab instances in parallel (up to now we run our tests sequentially and each one is starting a new Matlab instance via an ActX server).
So when I run the following code below
ML=ver('Matlab');
ML_Path=matlabroot;
ML_Ver=ML.Version;
parfor i = 1:3
NewMatlab = actxserver(['matlab.application.single.',ML_Ver])
Answer = NewMatlab.Feval('test',1);
NewMatlab.Quit;
NewMatlab.release;
end
the Matlab instances are called sequentially (test is just a very simple script that sums up a few numbers).
However if I start a new Matlab via command line
ML=ver('Matlab');
ML_Path=matlabroot;
ML_Ver=ML.Version;
parfor i = 1:3
dos('matlab -nodesktop -minimize -wait -batch "test"');
end
it works. I see that these two methods are quite different in the handling of starting Matlab, but the first approach would be
If you want each iteration of your test to run in a completely separate MATLAB instance, you could use the batch function, like this:
for i = 1:3
j(i) = batch(#test, nOut, {argsIn...});
end
% Later, collect results
for i = 1:3
wait(j(i)), fetchOutputs(j(i))
end
Or, you could simply use parfor directly
parpool() % If necessary
parfor i = 1:3
out{i} = test(...)
end
(You only need to call parpool if no pool is currently open, and you have your preferences set so that a pool is not automatically created when you hit the parfor).

Is it possible to change two function using parfor loop?

Suppose I have two functions written on different scripts, say function1.m and function2.m The two computation in the two functions are independent (Some inputs may be the same, say function1(x,y) and function2(x,z) for example). However, running sequentially, say ret1 = function1(x,y); ret2 = function2(x,z); may be time consuming. I wonder if it is possible to run it in parfor loop:
parfor i = 1:2
ret(i) = run(['function' num2str(i)]); % if i=1,ret(1)=function1 and i=2, ret(2)=function2
end
Is it possible to write it in parfor loop?
Your idea is correct, but the implementation is wrong.
Matlab won't let you use run within parfor as it can't make sure it's a valid way to use parfor (i.e. no dependencies between iterations). The proper way to do that is to use functions (and not scrips) and an if statement to choose between them:
ret = zeros(2,1);
parfor k = 1:2
if k==1, ret(k) = f1(x,y); end
if k==2, ret(k) = f2(x,z); end
end
here f1 and f2 are some functions that return a scalar value (so it's suitable for ret(k) and each instance of the loop call a different if statement.
You can read here more about how to convert scripts to functions.
The rule of thumb for a parfor loop is that each iteration must be standalone. More accurately,
The body of the parfor-loop must be independent. One loop iteration
cannot depend on a previous iteration, because the iterations are
executed in a nondeterministic order.
That means that every iteration must be one which can be performed on its own and produce the correct result.
Therefore, if you have code that says, for instance,
parfor (i = 1:2)
function1(iterator,someNumber);
function2(iterator,someNumber);
end
there should be no issue with applying parfor.
However, if you have code that says, for instance,
persistentValue = 0;
parfor (i = 1:2)
persistentValue = persistentValue + function1(iterator,someNumber);
function2(iterator,persistentValue);
end
it would not be usable.
Yes. It is possible.
Here's an example:
ret = zeros(2,1);
fHandles = {#min, #max};
x = 1:10;
parfor i=1:2
ret(i) = fHandles{i}(x);
end
ret % show the results.
Whether this is a good idea or not, I don't know. There is overhead to setting up the parallel processing that may or may not make it worthwhile for you.
Typically the more iterations you have computed, the more value you get from setting up a parfor loop as the iterations are sliced-up and sent non-deterministically to the separate cores for processing. So you're getting use of 2 cores right now, but if you have many functions this may improve things.
The order that the iterations are run is not guaranteed (it could be that one core gets assigned a range of values for i, but we do not know if it those values are taken in order or randomly), so your code can't depend on other iterations of the loop.
In general, the MATLAB editor is pretty at flagging these issues ahead of time.
EDIT
Here's a proof of concept for a variable number of arguments to your different functions
ret = zeros(2,1);
fHandles = {#min, #max};
x = 1:10; % x is a 1x10 vector
y = rand(20); % y is a 20x20 matrix
z = 1; % z is a scalar value
fArgs = {{x};
{y,z}}; %wrap your arguments up in a cell
parfor i=1:2
ret(i) = fHandles{i}([fArgs{i}{:}]); %calls the function with its variable sized arguments here
end
ret % show the output
Again, this is just proof-of-concept. There are big warnings showing up in MATLAB about having to broadcast fArgs across all of the cores.

Bad version or endian-key in MATLAB parfor?

I am doing parallel computations with MATALB parfor. The code structure looks pretty much like
%%% assess fitness %%%
% save communication overheads
bitmaps = pop(1, new_indi_idices);
porosities = pop(2, new_indi_idices);
mid_fitnesses = zeros(1, numel(new_indi_idices));
right_fitnesses = zeros(1, numel(new_indi_idices));
% parallelization starts
parfor idx = 1:numel(new_indi_idices) % only assess the necessary
bitmap = bitmaps{idx};
if porosities{idx}>POROSITY_MIN && porosities{idx}<POROSITY_MAX
[mid_dsp, right_dsp] = compute_displacement(bitmap, ['1/' num2str(PIX_NO_PER_SIDE)]);
mid_fitness = 100+mid_dsp;
right_fitness = 100+right_dsp;
else % porosity not even qualified
mid_fitness = 0;
right_fitness = 0;
end
mid_fitnesses(idx) = mid_fitness;
right_fitnesses(idx) = right_fitness;
fprintf('Done.\n');
pause(0.01); % for break
end
I encountered the following weird error.
Error using parallel.internal.pool.deserialize (line 9)
Bad version or endian-key
Error in distcomp.remoteparfor/getCompleteIntervals (line 141)
origErr =
parallel.internal.pool.deserialize(intervalError);
Error in nsga2 (line 57)
parfor idx = 1:numel(new_indi_idices) % only assess the necessary
How should I fix it? A quick Google search returns no solution.
Update 1
The weirder thing is the following snippet works perfectly under the exactly same settings and the same HPC. I think there might be some subtle differences between them two, causing one to work and the other to fail. The working snippet:
%%% assess fitness %%%
% save communication overheads
bitmaps = pop(1, new_indi_idices);
porosities = pop(2, new_indi_idices);
fitnesses = zeros(1, numel(new_indi_idices));
% parallelization starts
parfor idx = 1:numel(new_indi_idices) % only assess the necessary
bitmap = bitmaps{idx};
if porosities{idx}>POROSITY_MIN && porosities{idx}<POROSITY_MAX
displacement = compute_displacement(bitmap, ['1/' num2str(PIX_NO_PER_SIDE)]);
fitness = 100+displacement;
else % porosity not even qualified
fitness = 0;
end
fitnesses(idx) = fitness;
%fprintf('Done.\n', gen, idx);
pause(0.01); % for break
end
pop(3, new_indi_idices) = num2cell(fitnesses);
Update 2
Suspecting [mid_dsp, right_dsp] = compute_displacement(bitmap, ['1/' num2str(PIX_NO_PER_SIDE)]); causes me trouble, I replace it with
mid_dsp = rand();
right_dsp = rand();
Then, it works! This proves that this is indeed caused by this particular line. However, I do have tested the function, and it returns two numbers correctly! Since the function returns value just as rand() does, I can't see any difference. This confuses me more.
I had the same issue and it came out that Matlab 2015 is reserving all necessary memory resources for each of the loops in the parfor resulting in memory break shortage.
The error message is tricky. After fine tuning the code in the loop and providing 120GB of RAM from the SSD through system setting in Pagefile in Windows 10, the parfor executed beautifully.
After working a while on my own similar code block, I've decided that this is actually a memory issue.
I'm using a 6 core 4GHz CPU and 8 gigs of RAM and seen this issue (on MATLAB 2014b) when I set the worker count high, and did not have any problems with low worker counts.
When I use 6 or more workers (which is not ideal I know), memory consumption is high and this error message pops out sporadically. Also I have seen various out of memory errors in my tests.
I havent seen the error when I use 5 or less workers thus far, and I'm pretty sure some memory limit (possibly inside a java code block) is causing this issue by preventing some of the results' integrity (or existance)
Hope you can resolve this issue by reducing the worker count.

Matlab parallel for loop or Matlab open pool

I am trying to to some computations and I would like to do it in parallel using parfor or by Opening the matlabpool.. as the current implementations is too slow:
result=zeros(25,16000);
for i = 1:length(vector1) % length is 25
for j = 1:length(vector2) % length is 16000
temp1 = vector1(i);
temp2 = vector2(j);
t1 = load(matfiles1(temp1).name) %load image1 from matfile1
t2 = load(matfiles2(temp2).name) % load image2 from matfile2
result(i,j)=t1.*t2
end
end
its works fine but I would really like to know if there is a way to speed thing up ...
Thanks a lot in advance!
Using a parfor loop and opening a matlabpool go together. Opening the matlabpool provides your MATLAB session with dedicated workers with which it can run the body of your parfor loop. So, you could change your code to something like this:
matlabpool open local 4 % or however many cores you have
parfor i = ...
...
end
Before running your code in parallel, I would definitely recommend using the MATLAB profiler to ensure you understand where the time is being spent running your code. (I'm a little surprised that hoisting the load into t1 into the outer loop has no effect - the profiler presumably should therefore show that the load calls take very little time compared to the rest of your algorithm).