So basically what I want to do is have my main program to do some calculations, unrelated to a parallel program. The parallel program is constantly checking for some event to come true, and when it does, I want the main program to freeze and start another parallel job. Is it possible to do so in Matlab?
You can imagine it as a robot riding (main program) and at the same time checking its sensor data (worker). When it approaches an obstacle, a program to avoid the obstacle is started.
Thanks in advance,
Rugile :)
The best solution to this that I have seen is to use a Matlab timer object.
Implementation code would look something like this:
%Setup timer
t = timer;
t.ExecutionMode = 'fixedSpacing'; %See `docsearch Timer Object Execution Modes` for explaination
t.Period = 1; %Number of seconds after one execution to the start of the next
t.TimerFcn = #checkAndExecuteParallelJob
start(t);
%Start main job
mainJob();
In another file
function checkAndExecuteParallelJob
if (conditionIsFalse)
%Fast return
return;
end
%..Code to execute parallel job. This will block the main execution
Matlab is not multi-threaded, so the execution of a timer callback function will interrupt and block the execution of any main function. Timers can also interrupt each other, sometimes but not always, with a complex set of rules that I once tried to reverse engineer but have since given up on. However, for the relatively simple problem you laid out, I think that a timer object would be sufficient.
Related
So I'm sunning a code which solves an equation over a given period of time. As one would expect, the solution will change as time evolves so I wanted to create some sort of for loop which has the effect of creating "snapshots", which is to say I intend to pause the output at set intervals.
How might I go about implementing such a function?
I was hoping to implement something which pauses the code at defined intervals and then resumes execution on a button press.
Suppose I am running a function fun(), but I don't have access to inside it (so I can't put conditions inside it).
The function might be slow, for some inputs. How can I terminate the program if it takes more than a certain amount of time?
Update: I am testing the function for various set of inputs. For some of them it takes more. I want to skip the ones which take too long, and move to the next input.
Unfortunately MATLAB's single-threaded nature makes this more complicated than it should be. My first inkling is to use a timer, but even timer callbacks will not interrupt a busy MATLAB, as all M-Code is executed from the same thread.
I would solve this problem by calling the function from another MATLAB process, and monitoring that process. You can use the built-in SYSTEM function to call MATLAB, and use the -r command line argument to specify the name of the script to run. The pseudocode would look something like this. This rough and untested but should give you the idea:
% Create Timer object
timerObj = timer();
% set timer properties, with 60 second interval
set(timerObj, 'executionMode', 'singleShot', 'StartDelay', 60, 'timerFcn', #timerCallback);
% call MATLAB. It will run in background
system( 'matlab.exe -r myscript &' );
function timerCallback(varargin)
% if the other matlab process is still running when the timer is elapsed, kill it. perhaps use another system() call to run taskkkill.exe (if on windows)
The program below contains a timer object definition followed by its start command. Then the program continues executing other statements.
My question is whether TimerFcn will be called exactly after 0.01 sec, or will it wait until the for-loop completes for the timer callback function to fire?
% My timer object
t = timer('TimerFcn',#(x,y)G2(z), 'StartDelay',0.01);
start(t);
% Other program statements
for i=1:m
...
end
Bottom line is that MATLAB is effectively single-threaded. So if a long operation is currently executing, the timer callback will not get a chance to run, and according to the timer object properties (read about BusyMode), will instead add the event to a queue which MATLAB will eventually go through when it first gets a chance..
From what I understand (this is my own speculation), MATLAB timers can interrupt execution in between statements, but NOT during a lengthy one.
So in theory it should run after 0.01 second, but there are no guarantees...
The documentation says the following:
Note: The specified execution time and the actual execution of a timer
can vary because timer objects work in the MATLAB single-threaded
execution environment. The length of this time lag is dependent on
what other processing MATLAB is performing. To force the execution of
the callback functions in the event queue, include a call to the
drawnow function in your code. The drawnow function flushes the event
queue.
There is also this note on another doc page:
Note: Callback function execution might be delayed if the callback involves a CPU-intensive task such as updating a figure.
I created a timer that executes every 0.1 seconds. It calls a function that reads data and then updates the property of an object. When I start the timer, MATLAB displays the "Busy" signal at the bottom of the command window. MATLAB becomes unresponsive and I cannot halt the timer using the stop() function. My only recourse is to use Ctrl-C.
I determined the problem to be the processing time of the timer callback function was longer than the calling period and I presume no other MATLAB code could squeak into the stack/queue. This makes me somewhat worried about relying upon timers. My goal is to continuously make measurements from several devices, store them in an object, and need MATLAB to do other things in between these measurements. Also, I cannot afford to miss a measurement.
I am creating an app that responds to user input and provides the user with real time information, so I chose a fast period thinking it would produce a snapping UX. Since I am committed to using MATLAB I could not think of a better way of implementing this functionality than using a timer object. So the first question is, do timer objects seem like the right tool for the job I describe above?
Second, if I am to use timer objects would someone please share their experience about common mistakes or pitfalls using timers? Or has someone any advice on how to best implement timer objects? Is there a practical limit to the number of timer objects that can be used simultaneously? What is the best way to determine the optimal frequency of a timer object?
Thanks!
I would think that 0.1 seconds is pushing it for reliability, especially if you have multiple timers going at once, and especially if you want a user interface to be responsive at the same time as well.
MATLAB is basically single-threaded. There are exceptions, for example the lower level math routines call BLAS in a multithreaded way that speeds them up a lot. You can also write MEX code in C that is multithreaded, and call that from MATLAB. But there's basically one true thread that all your code runs on.
Timer objects are also an exception in a way. When you create a timer object, underneath that there's a java timer object, which is running on a separate java thread. But when any of its callbacks fire, it calls back into MATLAB to execute them, which happens on the one true thread.
If you cannot afford to miss a measurement, you'll need to set the BusyMode property of your timers to queue rather than the default drop, which will mean that if any of the callbacks take longer than 0.1 seconds to execute, they will back up - and you have to fit in any user interface actions as well.
In addition, MATLAB doesn't (and couldn't) make any real guarantees about the precision of how fast or regularly the timer callbacks will execute. If Windows suddenly decides to run a virus scan, or update itself etc, MATLAB will lose priority and that will mess things up. If you were firing timers every 10 seconds, or even every 1 second, it's in all likelihood going to be roughly accurate. But if you're firing them every millisecond, you can't expect it to be reliable - you'd need a proper real time environment for that. 0.1 seconds seems borderline to me, and I'd expect its reliability to depend on what exactly you were doing in those 0.1 seconds, and what else was going on as well (and what computer you're running, as well).
To answer your last questions (max number of timers, optimal timer frequency etc) - there's no general answer, just try it and work out what happens with a range of values in your particular situation.
If it turns out that it's not reliable enough, you could either try:
Doing the data acquisition in another faster way (e.g. in C), maybe in a separate process, then calling that from MATLAB via MEX, perhaps with some sort of buffering to smooth things out.
Turning to some the other MathWorks products (e.g. Simulink, Simulink Coder, some of the System Toolboxes) that are designed for developing properly real time systems.
Hope that helps!
I'm using Psychtoolbox in MATLAB to run a behavioral psychology paradigm. As part of the paradigm, users have to view a visual stimulus and respond to it using some input mechanism. For a keyboard, this works as follows:
show stimulus
poll keyboard for response
if no response detected, loop back to 1
if response detected, break and move on with script
This works fine for a keyboard, as step 2 takes between 1-2 ms. The problem comes when I use an alternate input mechanism; in that case, step 2 takes ~20 ms. (I need this alternate input to run the study, and that should be considered immutable fact.) As the stimulus changes with a very short timespan, this added delay breaks the task.
My current thought is to try to use the parallel processing, such that one thread shows the stimulus, and another thread polls the keyboard. I'm currently using the Parallel Computing Toolbox to do this. The problem I'm having is that I don't know how to direct keyboard input to a "parallelized" thread. Does anyone know (1) whether it's possible to direct keyboard input to a thread / have a thread send a visual signal to a monitor, and if yes, (2) how to do it?
Also, if anyone has any better ideas as to how to approach this problem, I'm all ears.
According to this MATLAB newsgroup thread, it appears that threads can't modify graphics objects. Only the desktop MATLAB client can do that. This means that you can't handle updating of graphics from a thread, and I can confirm this as I tried it and wasn't able to modify figures or even the root object from a thread.
However, I think you may be able to do the main graphics updating in MATLAB while a thread handles polling for your input. Here's a sample function for continuously updating a display until a thread waiting for input from KbCheck is finished running:
function varargout = plot_until_input
obj = createJob(); %# Create a job
task = createTask(obj,#get_input,4,{deviceNumber}); %# Create a task
submit(obj); %# Submit the job
waitForState(task,'running'); %# Wait for the task to start running
%# Initialize your stimulus display here
while ~strcmp(get(task,'State'),'finished') %# Loop while the task is running
%# Update your stimulus display here
end
varargout = get(task,'OutputArguments'); %# Get the outputs from the task
destroy(obj); %# Remove the job from memory
%#---Nested functions below---
function [keyIsDown,secs,keyCode,deltaSecs] = get_input(deviceNumber)
keyIsDown = false;
while ~keyIsDown %# Keep looping until a key is pressed
[keyIsDown,secs,keyCode,deltaSecs] = KbCheck(deviceNumber);
end
end
end
I was able to successfully run the above function with some simple plotting routines and replacing the code in get_input with a simple pause statement and a return value. I'm unsure whether KbCheck will work in a thread, but hopefully you will be able to adapt this for your needs.
Here's the documentation for the Parallel Computing Toolbox functions used in the above code: createJob, createTask, submit, waitForState, destroy.
I don't know of a way how you could do this with parallel processing.
However, a feature you might be able to use is the timer object. You would set up the timer object to poll the input mechanism, and, if anything is detected, change the value of a global variable. Then, you start your stimulus routine. In the while-loop in which you're updating the display, you keep checking the global variable for a change from the timer object.
You have to tackle the 20ms latency in your input device. If it's too slow then get another input device. You can get good sub-millisecond timing with proper response boxes.
All this talk about threading is misguided and not applicable to the PTB framework.