1

I have a C++ program using MPI where I would like each process (up to 32) to write to a file. I am using a small, test data set consisting of 100 doubles distributed evenly across the processes. Here is how the output is formatted thus far:

  data_sink.Write(&d_p[i], 1, MPI::DOUBLE);
  data_sink.Write(&space, 1, MPI::CHAR);
  data_sink.Write(&r_p[j], 1, MPI::DOUBLE);
  data_sink.Write(&new_line, 1, MPI::CHAR);

What is the best way to format this output so that the result can be directly interpreted by GNUPlot?

Jonathan Dursi
  • 50,107
  • 9
  • 127
  • 158
vrume21
  • 561
  • 5
  • 15

1 Answers1

5

I'm assuming here that data_sink is an MPI::File. Enough code to be able to reproduce your output would be helpful.

The first thing to know is that MPI-IO routines output in binary; outputting the space and the newline character after each value won't change that. But the other thing to know is that gnuplot can read binary files just fine. So here is a little MPI-IO code that outputs a sine wave, with each process getting 20 points of the whole domain:

#include <mpi.h>
#include <cmath>

int main(int argc, char **argv) {

    int rank, size;
    const int nperrank = 20;
    double *data = new double[2*nperrank];

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&size);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    int totnpts = nperrank * size;
    double dx = (2.*3.14159/totnpts);
    double left = rank * nperrank * dx;

    for (int i=0; i<nperrank; i++) {
        double x = left + dx*i;
        double sinx = sin(x);

        data[2*i] = x;
        data[2*i+1] = sinx;
    }

    MPI_File file;
    MPI_File_open(MPI_COMM_WORLD, "out.dat", MPI_MODE_WRONLY |  MPI_MODE_CREATE,
                    MPI_INFO_NULL, &file);

    MPI_Status status;
    MPI_File_write_at_all(file, 2*rank*nperrank*sizeof(double),
                            data, 2*nperrank, MPI_DOUBLE, &status);

    MPI_File_close(&file);

    MPI_Finalize();
    return 0;
}

And here's the output of running it and plotting:

$ mpicxx -o io io.cc
$ mpirun -np 4 ./io
$ gnuplot

    G N U P L O T
    Version 4.2 patchlevel 6
    [...]


Terminal type set to 'x11'
gnuplot> plot 'out.dat' binary format="%lf%lf" using 1:2 with linespoints
gnuplot>

enter image description here

Jonathan Dursi
  • 50,107
  • 9
  • 127
  • 158
  • 1
    The third thing to know is, don't get too attached to the C++ MPI bindings; they've been deleted from the standard as of MPI 3.0. While most MPI implementations will continue to have them kicking around, not-really-supported, for some time, your best bet for new code development is the C bindings, as used above. – Jonathan Dursi Apr 14 '13 at 02:23
  • Sorry to be unclear, will note that in the future. Thanks for your answer, the problem was that I simply didn't know how to have GNUPlot interpret the data output from my code. Your example let me address the issue. An aside, why have the C++ bindings been removed from the standard? I'm using "Using MPI-2" and there's no mention (at least in what I've read) of such a change. – vrume21 Apr 14 '13 at 05:53
  • The story behind the C++ bindings is well described here: http://blogs.cisco.com/performance/the-mpi-c-bindings-what-happened-and-why/ . Basically, there was dissatisfaction with the C++ bindings but not enough expertise on the committee to keep things up to date or sufficiently featureful, so rather than let them stagnate, they were removed. The committee is going to stick to its knitting, getting the API and the basic C/Fortran bindings correct, and the hope is that the community will provide good C++ bindings (a la Boost's MPI-1 support) as it does with python, java, etc. – Jonathan Dursi Apr 14 '13 at 12:27