Run two Matlab functions simutaneously in parallel

My friend gave me a project: run two matlab loops (can be put in two functions) simultaneously. They have to be synchronized. They have to start at the same time, and they have to synchronize every step in loop. The problem was simplified because the two loops with run with a fairly stable step size. So what I need do is to start the two functions at the same time with error less than 0.1ms.

To run two matlab functions, we need parallel computing, or simply use two matlab sessions. For two matlab sessions, we need make a feedback in one session to trigger the other session. There are different ways to make the trigger.

1. Use hard drive to communite between two session is one way. Basically, we need first initialize a start.ini file with -1:

fid=fopen('start.ini','w');
fprintf(fid,'%d',-1);
fclose(fid);

Then one session start function 1 and write 1 to the ini file:

fid=fopen('start.ini','w');
fprintf(fid,'%d',1);
fclose(fid);

In the other session, it keeps checking the ini file, it starts once it reads 1.

while 1
    fid=fopen('start.ini','r');
    k=fscanf(fid,'%d',1);
    fclose(fid);
    if k==1
    %-------- reset start.ini to -1 start ---------------%
        fid=fopen('start.ini','w');
        fprintf(fid,'%d',-1);
        fclose(fid);
    %-------- reset start.ini to -1 end ---------------%
        break
    end
end

This works in a lot of scenarios. Here the problem with this is it takes a few milliseconds, and it fluctuates. So this is not a good solution.

2. Use a shared memory. Ram should be faster than Hard Drive. Basically, we can have one session write a variable to the memory, and have the other session read it, just like writing and reading from hard drive, but faster. The problem is two matlab sessions use two separate workspaces residing in different memory locations, not shared.

Actually, if we could, creating a shared variable in CPU cache (register) is the fastest way to read and write a variable for a computer. But I can’t find anything in matlab about that.

There is method called DDE (Dynamic Data Exchange) that makes different applications communicate.  But I didn’t find anything that can make DDE work between two matlab session.

Then I found a matlab program sharedmatrix on mathworks: http://www.mathworks.com/matlabcentral/fileexchange/28572-sharedmatrix. This program creates a memory block that will be shared by two matlab sessions. I managed to compile it in Matlab 2010a and Ubuntu. But I can’t make it work. This program seems very unstable. When the second session read the shared memory, matlab crashes. So I gave up this method.

There are other methods to make the feedback, but I can’t think of a way that can really solve my problem.

3. Use parallel computing

Another method to make the synchronization is to use parallel computing. A more detailed post can be found here about parallel computing in matlab: https://alenblog.wordpress.com/2011/03/31/parallel-computing-in-matlab/.

Basically, we can have two threads that can call two functions simultaneously. The traditional multithreading is actually through time division. So the time actually not synchronized for the two functions. But I’m not sure what the time difference is. I found a post here, where basically some codes were written in c++ for multithreading, it can be compiled in matlab to MEX file, and then be called. But like in the comment, I got same errors when compiling:

mex mythreadprog.cpp

Error mythreadprog.cpp: 11 syntax error; found `MyThread’ expecting `;’
Error mythreadprog.cpp: 19 redeclaration of `mexFunction’ previously declared at .\mex.h 135
Warning mythreadprog.cpp: 23 assignment of pointer to void function(pointer to void) to pointer to int function(pointer to void)
Error mythreadprog.cpp: 33 syntax error; found `MyThread’ expecting `;’
Warning mythreadprog.cpp: 58 missing return value
Error mythreadprog.cpp: 33 undefined size for `void cdecl’
4 errors, 2 warnings

C:\PROGRA~1\MATLAB\R2007B\BIN\MEX.PL: Error: Compile of ‘mythreadprog.cpp’ failed.

The new multithreading parallel computing using multi-core computer is built in recent matlab versions and can really do the job.

I found different ways to do parallel computing in matlab. The way posted here is using parallel computing, but it doesn’t make the synchronization. The code is shown below:

 
funList = {@fun1,@fun2,@fun3};
dataList = {data1,data2,data3}; %# or pass file names 

parfor i=1:length(funList)
    %# call the function
    funList{i}(dataList{i});
end

Finally, I got a way using matlabpool open two labs, and use spmd to run two functions in two labs separately. labBarrier is used to synchronize the two labs. The code is shown below.

function data = main

struct data1 data2;
data1.x = 1;
data2.x = 2;
funList = {@fun1,@fun2};
dataList = {data1,data2}; % or pass file names 

matlabpool open 2
spmd
    labBarrier
	funList{labindex}(dataList{labindex})
end
matlabpool close

function y = fun1(data1)
time1=clock;
fprintf('%02d : %02d : %02f\n',time1(4),time1(5),time1(6))
labindex
pause(5)
disp('run f1');

function y = fun2(data2)
time2=clock;
fprintf('%02d : %02d : %02f\n',time2(4),time2(5),time2(6))
labindex
pause(5);
disp('run f2')

We can see the two functions are starts at the same time. But the clock command only shows to the accuracy of 1ms.

Retrieve data from .fig matlab figure file

1. If your fig file is opened, pull it to active current window.

To find what data you want, check properties: get(get(gca,’Children’)) .

Let’s say, you have a curve and want get data ‘XData’ and ‘YData”.

x = get(get(gca,’Children’),’XData’);

y = get(get(gca,’Children’),’YData’);

If you plot(x,y), you’ll get the same the same curve.

If your figure is not opened yet. You can open it and do 1.

We can also use gcf. gcf is the handle of the current figure; gca is the handle of the current axis.

“gca” is the same as “get(gcf,’Children’) “.

That means, we can also do this:

get(get(gcf,’Children’),’Children’),’XData’)

We can also break it down to steps with struct or objects using gca or gcf.

  • hAxes = get(gca);
  • hProperties = hAxes.Children;
  • x = get(hProperties, ‘XData’);

or

  • hFig  = get(gcf);     %save figure handle object to a struct
  • hAxes = hFig.Children;
  • hProperties = get(hAxes);
  • hLine = hProperties.Children;
  • x = get(hLine, ‘XData’);

2. We can open the figure and store the handle to a variable:

fighandle = openfig(‘myfigure.fig’), which is basically the same as “gcf” if we open the figure first. Then we can do the same thing as in 1.

get(get(fidhandle,’Children’),’Children’),’XData’)

3. We don’t open the figure, but load the figure file into a struct variable.

myFigStruct = load(myfigure.fig’,’-MAT’) ;

or

myFigStruct = load(‘-MAT’,myfigure.fig’);

Note: the root element of the figure is called ‘hgS_070000’ for
Matlab7+ figures – it’s called something else for figures saved in
Matlab6- (probably ‘hgS_06…’ or something).

Then find the data element in the hierarchy, like ‘XData’:

myFigStruct.hgS_070000.children.children.properties.XData

4. Save the data of the figure file to a .mat file.

  • open .fig file.
  • saveas(gcf,’mydata’,’mmat’)   %save data of the .fig file to .mat file called mydata.mat
  • load ‘mydata’
  • The object variable  ‘mat’ now contains all your data. To extract it from it, do: x1=mat{1}, x2=mat{2} etc.

5.  If the figure is a line, we can also use findobj or findall from the figure handle.

fighandle=openfig(‘myfigure.fig’);
ax=findall(fighandle,’Type’,’line’);
x=get(ax,’XData’);
y=get(ax,’YData’);

or

s=hgload(‘myfigure.fig’);
h = findobj(s,’Type’,’line’);
x=get(h,’xdata’);
y=get(h,’ydata’);

Matlab Matrix

  • Matrix A, B. What’s A(B)?

1. Elements of B are logical.

A =[1 2; 3 4]

1 2

3 4

B = [1 0; 1 0]

1 0

1 0

A(B) =

1 0

3 0

2. Elements of B are positive integers.

B = [1 1;2 2]

A(B) =

1 1

3 3

  • Matrix A is x dimension A(:,:,:…), how to copy A to matrix B(n,:,:,:,…)’s first dimension B(1,:,:,:…)?

d = size(A);

B = zeros([n size(A)]);

B( 1, : ) = A( : );

“include” a .m file into another .m file

If you’re trying to call the main function of another file inside your first
file, just call it like any other MATLAB function.
If you’re trying to call a subfunction in the second file from within your
first file, you can have the main function in the second file be a
“switchyard” that accepts the name of the subfunction to call:

% begin switchyard.m
function y = switchyard(fcn, x)
% Call as:
% y = switchyard(‘mycos’, 1:10);
% or
% y = switchyard(‘mysin’, pi);

y = feval(fcn, x);

function y = mycos(x)
y = cos(x);
function y= mysin(x)
y = sin(x);
% end switchyard.m

or you can have the main function return a handle to the subfunction and
call them that way:

% begin createhandles.m
function s = createhandles
% Call as:
% s = createhandles
% y1 = s.mycos(1:10);
% y2 = s.mysin(pi);

s.mycos = @mycos;
s.mysin = @mysin;

function y = mycos(x)
y = cos(x);
function y= mysin(x)
y = sin(x);
% end createhandles.m

If the other file is a script, just run it by typing the name of the script.