MRCPP comes with a printer class to handle standard output which is available by including:

#include "MRCPP/Printer"

The main purpose of this class is to provide (or suppress) any internal printing in MRCPP routines that might be useful for debugging. Also, it provides a sane printing environment for parallel computations that can also be used by the application program. E.g. by using the printing routines of this class, as opposed to the standard std::cout, only the master thread in a OpenMP region will provide any output while all other threads remain silent. Similarly, when running an application program in MPI parallel the mrcpp::Printer provides three different options for handling printed output (see examples below):

  • Only master rank prints to screen (stdout)
  • All ranks prints to screen (stdout)
  • All ranks prints to individual files

If you want only the master rank to print to an output file, this can be achieved by redirecting the output from the first option to a file (./program >file.out).

The main functionality of the MRCPP printer is given by the two macros printout and println (see below for details) which should replace the regular calls to std::cout. In addition there are a few helper functions and macros for convenience output.

Available functions

All mrcpp::print functions takes an integer print level as first argument. When the mrcpp::Printer is initialized with a given print level, only print statements with a lower print level will be displayed. All internal printing in MRCPP is at print level 10 or higher, so there is some flexibility left (levels 0 through 9) for adjusting the print volume within the application program.

Initialize the mrcpp::Printer with print level and options for parallel printing. No output is provided by the mrcpp::print routines unless the Printer is initialized.
Use scientific notation (e.g. 1.0e02) for floating point numbers.
Use fixed notation (e.g. 100.0) for floating point numbers.
Set new precision for floating point values, e.i. number of digits after the comma. Returns the old precision.
Get the current precision for floating point values.
Change the print level from this point onwards. Returns the old print level.
Get the current print level.
Set the line width (in number of characters) of the helper function output. Default is 60 characters.
Get the current line width (in number of characters).

Helper functions

Some convenience functions for printing output is provided within the mrcpp::print namespace. These functions use the data of the mrcpp::Printer class to provide pretty output of a few standard data types.

Print information on how MRCPP was built. Version number and git revision, which linear algebra library is used, and parallel options.
Print a full line of a single character.
Print a headline.
Print a footline, including a timer.
Print a floating point value, including unit.
Print a tree size (nodes and memory) and time.
Print the current memory usage of the this process.

Available macros

The following macros should replace the regular calls to std::cout:

Print a string with a given print level, no newline.
Print a string with a given print level, with newline.

The following macros will print a message along with information on where you are in the code (file name, line number and function name). Only macros that end with _ABORT will kill the program, all other will continue to run after the message is printed.

Prints a “Info: ” message, no abort.
Prints a “Warning: ” message, no abort.
Prints a “Error: ” message, no abort.
Prints a “Error: ” message and aborts the program.
You have passed an invalid argument to a function. Aborts program.
You have reached a function that is yet to be implemeted. Aborts program.
You have reached a point in the code that should not be reached, probably due to a bug or inconsistency. Aborts program.
You have reached an experimental part of the code, results cannot be trusted.
You have hit a known bug that is yet to be fixed, results cannot be trusted.


Using the print level to adjust the amount of output:

int level = 10;
mrcpp::Printer::init(level);            // Initialize printer with printlevel 10

println( 0, "This is printlevel  0");   // This will be displayed at printlevel 10
println(10, "This is printlevel 10");   // This will be displayed at printlevel 10
println(11, "This is printlevel 11");   // This will NOT be displayed at printlevel 10

Using headers and footers to get pretty output:

using namespace mrcpp;

Timer timer;                            // Start timer
project(prec, tree, func);              // Project function
double integral = tree.integrate();     // Integrate function
timer.stop();                           // Stop timer

print::header(0, "Projecting analytic function");
print::tree(0, "Projected function", tree, timer);
print::value(0, "Integrated function", integral, "(au)");
print::footer(0, timer);

This will produce the following output:

                Projecting analytic function
 Projected function         520 nds       16 MB    0.09 sec
 Integrated function               (au)  9.999999999992e-01
                  Wall time: 9.32703e-02 sec

As mentioned above, when running in MPI parallel there are three different ways of handling printed output (master to stdout, all to stdout or all to files). These can be chosen by adding appropriate arguments to init. The default setting will in a parallel environment have all MPI ranks printing to screen, but by adding MPI info to the printer, we can separate the output of the different ranks:

int level = 10;
int wrank, wsize;
MPI_Comm_rank(MPI_COMM_WORLD, &wrank);  // Get my rank
MPI_Comm_size(MPI_COMM_WORLD, &wsize);  // Get total number of ranks

// All ranks will print to screen

// Only master rank will print to screen
mrcpp::Printer::init(level, wrank, wsize);

// All ranks will print to separate files called filename-<rank>.out
mrcpp::Printer::init(level, wrank, wsize, "filename");