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)
Related
I'm using MATLAB R2014b. I designed a GUI that have a loop using parallel computing. First I will set the number of loops in this GUI and my program will start. Suppose that I want stop the program in middle of process. I should press CONTROL+C to stop MATLAB. I put a button to stop it and call a function in loop but it doesn't work when my program is running. These isn't any respond to this button when my program is running.
How can I solve this problem?
Thanks.
I presume by "parallel computing" you mean that your code is running is running in a parfor loop. The parfor loop is a synchronous construct which does not allow any other MATLAB commands to execute. If you wish to allow interactive use via a GUI, you need to use parfeval instead. This example shows how you can terminate parallel processing early.
One thing to bear in mind when using parfeval is that each call you make to that is a remote invocation, so you need to divide your problem into "sensible" sized chunks.
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.
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.
This question already has an answer here:
How to abort a running program in MATLAB?
(1 answer)
Closed 7 years ago.
I write a long running script in Matlab, e.g.
tic;
d = rand(5000);
[a,b,c] = svd(d);
toc;
It seems running forever. Becasue I press F5 in the editor window. So I cannot press C-Break to stop in the Matlab console.
I just want to know how to stop the script. I am current use Task Manager to kill Matlab, which is really silly.
Thanks.
Matlab help says this-
For M-files that run a long time, or that call built-ins or MEX-files that run a long time, Ctrl+C does not always effectively stop execution. Typically, this happens on Microsoft Windows platforms rather than UNIX[1] platforms. If you experience this problem, you can help MATLAB break execution by including a drawnow, pause, or getframe function in your M-file, for example, within a large loop. Note that Ctrl+C might be less responsive if you started MATLAB with the -nodesktop option.
So I don't think any option exist. This happens with many matlab functions that are complex. Either we have to wait or don't use them!.
If ctrl+c doesn't respond right away because your script is too long/complex, hold it.
The break command doesn't run when matlab is executing some of its deeper scripts, and either it won't log a ctrl sequence in the buffer, or it clears the buffer just before or just after it completes those pieces of code. In either case, when matlab returns to execute more of your script, it will recognize that you are holding ctrl+c and terminate.
For longer running programs, I usually try to find a good place to provide a status update and I always accompany that with some measure of time using tic and toc. Depending on what I am doing, I might use run time, segment time, some kind of average, etc...
For really long running programs, I found this to be exceptionally useful
http://www.mathworks.com/matlabcentral/fileexchange/16649-send-text-message-to-cell-phone/content/send_text_message.m
but it looks like they have some newer functions for this too.
MATLAB doesn't respond to Ctrl-C while executing a mex implemented function such as svd. Also when MATLAB is allocating big chunk of memory it doesn't respond. A good practice is to always run your functions for small amount of data, and when all test passes run it for actual scale. When time is an issue, you would want to analyze how much time each segment of code runs as well as their rough time complexity.
Consider having multiple matlab sessions. Keep the main session window (the pretty one with all the colours, file manager, command history, workspace, editor etc.) for running stuff that you know will terminate.
Stuff that you are experimenting with, say you are messing with ode suite and you get lots of warnings: matrix singular, because you altered some parameter and didn't predict what would happen, run in a separate session:
dos('matlab -automation -r &')
You can kill that without having to restart the whole of Matlab.
One solution I adopted--for use with java code, but the concept is the same with mexFunctions, just messier--is to return a FutureValue and then loop while FutureValue.finished() or whatever returns true. The actual code executes in another thread/process. Wrapping a try,catch around that and a FutureValue.cancel() in the catch block works for me.
In the case of mex functions, you will need to return somesort of pointer (as an int) that points to a struct/object that has all the data you need (native thread handler, bool for complete etc). In the case of a built in mexFunction, your mexFunction will most likely need to call that mexFunction in the separate thread. Mex functions are just DLLs/shared objects after all.
PseudoCode
FV = mexLongProcessInAnotherThread();
try
while ~mexIsDone(FV);
java.lang.Thread.sleep(100); %pause has a memory leak
drawnow; %allow stdout/err from mex to display in command window
end
catch
mexCancel(FV);
end
Since you mentioned Task Manager, I'll guess you're using Windows. Assuming you're running your script within the editor, if you aren't opposed to quitting the editor at the same time as quitting the running program, the keyboard shortcut to end a process is:
Alt + F4
(By which I mean press the 'Alt' and 'F4' keys on your keyboard simultaneously.)
Alternatively, as mentioned in other answers,
Ctrl + C
should also work, but will not quit the editor.
if you are running your matlab on linux, you can terminate the matlab by command in linux consule.
first you should find the PID number of matlab by this code:
top
then you can use this code to kill matlab:
kill
example:
kill 58056
To add on:
you can insert a time check within a loop with intensive or possible deadlock, ie.
:
section_toc_conditionalBreakOff;
:
where within this section
if (toc > timeRequiredToBreakOff) % time conditional break off
return;
% other options may be:
% 1. display intermediate values with pause;
% 2. exit; % in some cases, extreme : kill/ quit matlab
end
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.