interrupt a function when it takes too long

68 次查看(过去 30 天)
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.

回答(2 个)

John D'Errico
John D'Errico 2020-3-28
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.
  1 个评论
Alexandra McClernon Ownbey
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
Edric Ellis 2020-3-30
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.
  1 个评论
Alexandra McClernon Ownbey
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.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

产品


版本

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by