1

I'm writing a c++ program with MPI (C interface, no boost etc). In my program, I have many many outputs, either to cout or to files, which are only done on rank 0. Is there a good way to avoid writing if (rank == 0) cout << string?

There are two ways that are working on my computer with my MPI implementation, but both look shaky to me:

if (rank != 0)
  cout.setstate(ios_base::badbit);

This effectively disables output on all ranks but 0, but is it allowed? Will there be problems if I do this?

The other idea was to create an ofstream, which is not opened, and redirect the output there.

ostream* os;
ofstream nullstream;
if (rank == 0)
  os = &cout;
else
  os = &nullstream;
*os << "rank " << rank << endl;

This leaves nullstream in an error state, but effectively also disables output on all ranks that are not 0...

This question would seem common to me, so I'm sorry if it is already answered somwhere else. I didn't find an answer by searching and am happy for any redirection to an existing question.

skulda
  • 40
  • 5

2 Answers2

1

If you are willing to sacrifice portability to Windows systems, the proper way to mute the output on a POSIX system would be to redirect the standard output (and optionally the standard error) to /dev/null:

int main() {
   ...
   std::ofstream sink("/dev/null");

   if (rank != 0) {
     // Mute standard output
     std::cout.rdbuf(sink.rdbuf());
     // Optionally mute standard error
     std::cerr.rdbuf(sink.rdbuf());      
   }

   no_output_from_other_ranks_from_now_on();
   ...
}

Adapted from this answer.

Community
  • 1
  • 1
Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
0

I usually use preprocessor macros in some way, e.g.

#define COUT if(rank == 0) std::cout

You then simply write

COUT << string;

In my opinion, it is not clear whether this approach is better than one of yours, though.

gTcV
  • 2,446
  • 1
  • 15
  • 32