简体   繁体   中英

Pause Matlab without breakpoint

I have a script that is running a lot more time than I expected, it has been running for the last 3 days and only achieved 55% progress.

I would be perfectly happy to stop it at about 67% (I can live without the remaining 33%) But If I stop it now (ctrl+c or ctlr+break), I will lose all the data.

So is there a way to pause Matlab, perhaps into debug mode so I can check the variables without losing data?

The command (needs to be input manually before you start your function!)

dbstop if error

should catch a ctrl-c and leave you in debug mode.

I assume that you are doing something iteratively here and not relying on a built-in matlab function.

The way I usually solve the issue you have is to have an iteration counter and an if statement on that counter - when the condition is met, the statement has a breakpoint.

Something like this:

itCounter = 0;
itHalt    = 100;
while (someCondition)
    if (itCounter == itHalt)
        itCounter = 0; %<= Put a breakpoint here
    else
        itCounter = itCounter+1;
    end

    % Here you calculate away whatever you need to calculate
end

This way, in every itHalt iterations you get a breakpoint. Also, since we're dealing with matlab, you can change the value of itHalt as you see fit as soon as the breakpoint is hit.

I'm thinking to an alternative solution:

Let's have a script which basically consists of a main loop.

The script periodically writes information about the execution status (eg the number of iteration done) into a log file.

Also, the script periodically reads a number from the input file

1 meaning "continue"
0 meaning "stop the script execution"

At the beginning of the simulation, 1 is written in the file.

The user can read the log and can decide, at a certain point, to stop the script.

To do it, he has just to change 1 to 0 in the file as save it.

An if section exemines the value read on it.

If 1, nothing appens and the script continues running.
If 0, a break statement terminates the main loop and the script stops.

Just before the break statement, in the if section, the script saves the whole workspace into a .mat file.

The user has now access to MatLab (he can evan close MatLab) and can look, for example, at the output files generated up to that moment by the script, process them, make somo plot and so on.

Then he might decide to continue the execution of the script from the point in which it has been stopped.

At the begining of the script, a variable controls the way the script has to be executed:

Mode 0: start from the beginning
Mode 1: resume the script

An if - else section maneges the user selection.

In particular, if Mode 1 is selected, the script loads the previously saved workspace (stored in a .mat file), then the value of some variables of the script are set to the old values.

As an example: the script was stopped when the index of the for loop was, say, 100.

if the for loop is defined as

for i=start_loop_1:100000

in the Mode 1 of the if, start_loop_1 is set to i+1 (the value of i was saved in the .mat file).

This allows the loop "continuing" the execution from the point in which it was stopped.

In order to effectively "resume" the running of the script, some other variables used in the script might require to be managed in the same way in the Mode 1 section.

In tha case of a "big", "complicated" script this might be difficult, but ... not impossible

This solution has been implemented in the following script.

I can see a potential criticality consisting in the unlucky case in which the user saves the file containing 1,0 at the same time the script reads it.

% Flag to select the running mode
% Mode 0: start from the beginning
% Mode 1: resume the running
continue_my_script=1;
% if "Mode 1" has been selected, the "old" workspace is loaded and some
% variables are properly set
if(continue_my_script == 1)
   load my_script_data
   start_loop_1=i+1;
   start_loop_2=1;
% if Mode 0 has been selected some variables are set to their default value
else
   start_loop_1=1;
   start_loop_2=1;
% counter to enable writing of the log file
   cnt_log=0;
% counter to enable reading the "go / no go" input file
   cnt_go=0;
end
% Definition of the condition for writing the log file (in this case, a
% certain number of iterations")
log_iter=13;
% Definition of the condition for reading the "go / no go" input file (in
% this case, a certain number of iterations")
go_nogo_iter=20;
% Starting point of the "real script"
for i=start_loop_1:100000
% Increment the log counter
   cnt_log=cnt_log+1;
% if "log_iter" have been done, update the log file  
   if(cnt_log == log_iter)
      cnt_log=0;
      t=clock;
      fp=fopen('my_script_log.log','wt');
      fprintf(fp,'i= %d at %d %d %f\n',i,floor(t(4)),floor(t(5)),t(6));
      fclose(fp);
   end
% Another loop of the script      
   for j=start_loop_2:100000
      a(i,j)=sqrt(i);
   end
% Increment the "read input file" counter
   cnt_go=cnt_go+1;
% if "go_nogo_iter" have been done, read the go_nogo input file
   if(cnt_go == go_nogo_iter)
      cnt_go=0;
      fp1=fopen('my_script_go.log','rt');
      go_nogo=fscanf(fp1,'%d');
      fclose(fp1);
% If the user made the decision to stop the execution, save the workspace
% and exit; otherwise ... do noting, just continue running
      if(go_nogo == 0)
         save my_script_data
         break;
      end
   end
end

Hope this helps.

Okay, just to rephrase what I said in the comments with inputs from other users who commented. If your script is a MATLAB script, (Not a function), all the variables will be accessible from the workspace as long as you did not explicitly called 'clear' in the script if the script is stopped. In the usual case, ctrl+c will terminate the running script. The MATLAB variables used in the script will still be accessible from the MATLAB Workspace.

I don't think there is anything you can do while the code is already running, unless you put some hooks in place beforehand. Some of these other suggestions are good for that. Here is another one that I like: say you are leaving for the night, but coming back the next day, so you want your code to run for 14 hours and then stop and be waiting for you with however much data it got to in that time.

start_time = now;
final_time = start_time + 10/86400; % datenums are in days in Matlab, so +14/24 for 14 hours
% alternative: final_time = datenum('12-Aug-2015 09:00:00');

while now < final_time
    % do work
    disp('Working...')
    pause(1)
end

% potential clean up code to save results
disp('Clean up code.')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM