4

I have a MATLAB script that calls an executable (written in C++) using the system() command, like so:

exe_status = system('MySimulation.exe', arguments);

Since the executable can take quite a long time to run (up to several hours), I including a function within it that estimates the time remaining and outputs that to the console. If I run the executable outside of MATLAB, the Windows console looks roughly like this:

Simulation #B01 initiated...
Completion: 0.57%    Time remaining: 183 m 2 s

Using the \r character, the "completion" line rewrites itself every second. This works really well, and lets me know when to come back to analyze the data.

Unfortunately, calling the executable from the MATLAB console does not have the same effect. MATLAB waits until the executable has terminated before showing any console output at all, rendering my timer moot.

I've tried the following commands, but they all have the same behavior:

exe_status = system('MySimulation.exe', arguments);
exe_status = system('MySimulation.exe', arguments, '-echo');
exe_status = dos('MySimulation.exe', arguments);
exe_status = dos('MySimulation.exe', arguments, '-echo');

Unless I'm reading incorrectly, it seems that the MATLAB documentation suggests that '-echo' can be used to echo the command output while the executable is still running, but it has no effect on my particular program.

Jim
  • 142
  • 1
  • 2
  • 6
  • 1
    what did you get if you try something like `system('ping google.com')` ? Did you also get everything at the end of the ping test ? If it's not a problem for you, you should perhaps print a new line each time... – obchardon Jul 13 '16 at 21:45
  • @obchardon I do not, actually; it outputs to the console sequentially. As far as I can tell, `system('ping google.com')` behaves exactly as `ping google.com` does in the Windows console. – Jim Jul 13 '16 at 21:51
  • @obchardon printing the completion information as a new line (including the `\n` character) doesn't help - all the lines are printed at the executable's termination. – Jim Jul 13 '16 at 21:54
  • 1
    Is it any use to add `&` at the end? `exe_status = system('MySimulation.exe &');` – Luis Mendo Jul 13 '16 at 21:56
  • 1
    Check out [this](http://stackoverflow.com/questions/31306845/matlab-display-dos-command-output-to-static-text) thread and [this one](http://de.mathworks.com/matlabcentral/answers/71078-command-window-output-to-gui). It's a bit hacky, but may work. – Matthias W. Jul 13 '16 at 21:58
  • 1
    You need a second output parameter: [status,results] = system('comp', '-echo'); – mhopeng Jul 14 '16 at 05:34
  • @LuisMendo adding `&` to the command allows the executable to run in the background, i.e. it opens up a Windows console. Unfortunately, it also means that the MATLAB script continues onwards. Since the rest of the script analyzes data files built by the executable, this isn't a workable solution. – Jim Jul 14 '16 at 14:01
  • @mhopeng adding a second output parameter doesn't change the behavior. – Jim Jul 14 '16 at 14:08
  • Can you show us the print statement from your C++ exe? – mhopeng Jul 15 '16 at 20:46

2 Answers2

1

I got curious so I tried a few things. I tried a bash script, a c executable, and a python script, and all of them display their output the Matlab command window in "real time", which is the desired behavior for the question. I could not re-create the situation described in the question.

So I suspect either:

a) that whatever method you are using to overprint the same line is the problem. It may not be the use of \r, it might be related to the specific print method you are using in your C++ executable. I would try not using an overprint, and just print the status on a new line with the simplest print statement you can think of.

or,

b) the problem is OS-specific.

For completeness, here are the details about what I tried and the results (environment and print statement):

  1. bash script; echo ""
  2. compiled c code; printf("\n")
  3. python 2.7 script; print("".format() )
  4. os built-in ping program (as described in comments)

I ran this in Matlab, using the system command, for example system('./timer_out');. In all cases:

-Printed output appeared "in real time" if there was no second output variable, regardless of using the '-echo' flag or trailing semicolon, e.g.:

tic; system('./timer_out'); toc

-Printed output was suppressed if an output variable was given, e.g.:

tic; [s,r]=system('./timer_out'); toc

-Printed output appeared in real time if an output variable was given and the '-echo' flag was used, e.g.:

tic; [s,r]=system('./timer_out','-echo'); toc

This behavior is in accordance with the documentation. These tests used Matlab R2015b on OS X.

mhopeng
  • 1,063
  • 1
  • 7
  • 17
  • Well, I can rule out the overprint as the source of the issue. I disabled the updating "completion" line and it didn't affect the MATLAB console behavior. I have print statements both before and after the simulation, which takes about a minute to run. Both statements still appear simultaneously, about a minute after initiating the executable. Thanks for the details, though - I'll try to replicate the steps you took to try and narrow down the issue. For the record, I'm running on Windows 7. – Jim Jul 18 '16 at 15:58
1

I suppose my original question was worded too literally - I found a solution by tinkering with the C++ code instead of the MATLAB code. Specifically, I added std::endl or std::flush to the ends of console print commands, like so:

std::cout << "Simulation #B01 initiated..." << std::endl;

My guess is that flushing the stream prompts MATLAB to display contents of the stream to the console in "real time" (more or less), which is something the Windows console does not require on my particular computer with my particular operating system, etc. I'm sure there's a life lesson about portability here somewhere, but I don't know nearly enough about what I'm doing to frame it properly.

As a side note, I've noticed that MATLAB does not properly recognize the carriage return character \r in the console. In order to prevent my executable from spamming the console with potentially thousands of lines of updated status, I've replaced my old updating line function

void time_remaining( ... ) {

    std::string completion_update = ( ... );

    std::cout << completion_update << "\r";

}

with a slightly more complex one

int time_remaining( string_length, ... ) {

    for(i = 0; i < string_length; i++) std::cout << "\b";

    std::string completion_update = ( ... );

    std::cout << completion_update << std::flush;

    string_length = completion_update.length();

    return string_length;

}

which relies on the backspace character \b and the character length of the previous iteration of the string completion_update.

Jim
  • 142
  • 1
  • 2
  • 6