interrupt a function when it takes too long

54 views (last 30 days)
Is there a way to interrupt a function that has been taking too long in a for loop and continue to the next iteration? I am calling a function inside a for-loop and know about how long it should take for that function to converge. If it doesn't converge, I would like to move to the next iteration. Would using parfor be the best method?
I know there is a previous post answering this question, but that was an old version of matlab. I am wondering if this capability has been added since then.

John D'Errico on 28 Mar 2020
This is not what parfor is designed to solve, nor even what you could reasonably solve with parfor.
Since you are calling the function inside a for loop, change how you set up the loop. Use a while loop instead, where you keep track of the time consumed, or perhaps the number of iterations. Stop the loop when you have spent too much time. Since a while loop is based on a test anyway, this becomes a simple thing. You might decide to loop until EITHER you achieve the convergence tolerance, OR the maximum number of iterations has been hit, OR the total time consumed has been exceeded. As I said, this is one of the things a while loop is designed to do.
A rough outline of code MIGHT be:
errortol = 1.e-8;
maxiter = 1000;
maxtime = 10;
iter = 0;
tstart = tic;
tcurrent = tstart;
while (iter < maxiter) && ((tcurrent - start) < maxtime) && (currenterror > errortol)
% increment the iteration counter
iter = iter + 1;
% Perform whatever stuff you need to do here.
% To compute a test for convergence, you will need to compute the
% change in your objective, (or however you will predict convergence.)
currenterror = ...
% How much time has been spent in this particulr process?
tcurrent = toc;
end
So something like that. The code I've shown is more pseudo-code than real code, since I have no idea what iterations you are doing.
As you can see, the while loop iterates only as long as all of the conditions are true, what you want to see happen.
this will not work. using a while loop only works if i check how long the function takes after the fact. I need to check it simultaneously (hence my question for parfor).

Edric Ellis on 30 Mar 2020
The simplest approach would be to modify the potentially long-running function so that it checks whether it has exceeded its time budget. You haven't told us anything about that function, so it's not clear whether or not this might work for you.
If you aren't able to modify this function, you could possibly use parfeval to run the function on a worker process, and monitor the time taken on the client. Something a bit like this:
for idx = 1:N % your outer for-loop
% Invoke your function on a worker
fut = parfeval(@maybeLongRunningFunction, 1, <args>);
% Block for up to maxTime seconds waiting for a result
didFinish = wait(fut, 'finished', maxTime);
if ~didFinish
% Execution didn't finish in time, cancel this iteration
cancel(fut);
else
% Did complete, retrieve results
out(idx) = fetchOutputs(fut);
end
end
If this approach works, you might even be able to run multiple copies of your function simultaneously by making multiple calls to parfeval.
I have a method of characteristics code written in fortran77. I wrote a wrapper in matlab to help me quickly iterate through different input values. These values don't always converge in the MOC code, which causes the fortran script to continue to run. The code only takes a few seconds to run when it converges. I wanted to add functionality that would continue to the next iteration of the MOC if the current iteration did not converge quickly.

R2017a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!