Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am reading "Using MPI-2" and try to execute the code myself. I specified MPI_MODE_CREATE for MPI_File_open, but it actually does not create a new file, instead, it overwrites the previous file with the same name. I happen to find this out when first running with more processes, and then with fewer processes. My MPI version is openmpi 1.8.1.

Here is the code

#include <stdio.h>
#include <mpi.h>
#define BUFSIZE 4
int main(int argc, char **argv)
{
    int map[BUFSIZE], i, rank , size;
    char buf[BUFSIZE];
    MPI_File fh;
    MPI_Datatype filetype;
    MPI_Status status;
    MPI_Offset disp=0;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    for(i=0;i<BUFSIZE;i++)
    {
//      buf[i]=size*i+rank+'0';
        buf[i]=size*i+rank+'A';
        map[i]=size*i+rank;
    }
    MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
    MPI_Type_create_indexed_block(BUFSIZE, 1, map, MPI_CHAR, &filetype);
    MPI_Type_commit(&filetype);
    MPI_File_set_view(fh, disp, MPI_CHAR, filetype, "native", MPI_INFO_NULL);
    MPI_File_write_all(fh, buf, BUFSIZE, MPI_CHAR, &status);
    MPI_File_close(&fh);
    MPI_Type_free(&filetype);
    MPI_Finalize();
    return 0;
}

Here is the file content when I run with 6 processes

ABCDEFGHIJKLMNOPQRSTUVWX

Then I modified it a little bit. Substitute

buf[i]=size*i+rank+'A';

with

buf[i]=size*i+rank+'0';

and run with 2 processes, the file is as follows

01234567IJKLMNOPQRSTUVWX
share|improve this question

1 Answer 1

up vote 3 down vote accepted

This is correct behaviour - MPI_MODE_CREATE "creates the file if it does not exist", and has no effect if it does; as the documentation says, exactly like the corresponding POSIX O_CREAT.

For whatever reason, there isn't an MPI_MODE_* equivalent to O_TRUNC which would clobber the file if it already exists; for that you'd have to open with MPI_MODE_CREATE|MPI_MODE_EXCL, check to see if the open fails, and if so, delete the file and repeat (or maybe open it with MPI_MODE_DELETE_ON_CLOSE, close it, and then re-open it)

Coding it up both ways:

#include <stdio.h>
#include <mpi.h>
#define BUFSIZE 4
int main(int argc, char **argv)
{
    int map[BUFSIZE], i, rank , size;
    char buf[BUFSIZE];
    MPI_File fh;
    MPI_Datatype filetype;
    MPI_Status status;
    MPI_Offset disp=0;

    if (argc != 3) {
        fprintf(stderr,"Usage: %s letters|numbers test|delete|none\n", argv[0]);
        exit(-1);
    }

    int letters=0;
    if (!strcasecmp(argv[1],"letters"))
        letters = 1;

    int test=0;
    if (!strcasecmp(argv[2],"test"))
        test = 1;
    int delete = 0;
    if (!strcasecmp(argv[2],"delete"))
        delete = 1;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    for(i=0;i<BUFSIZE;i++)
    {
        if (letters)
            buf[i]=size*i+rank+'A';
        else
            buf[i]=size*i+rank+'0';

        map[i]=size*i+rank;
    }

    if (test) {
        int err = MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_EXCL|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
        if (err != MPI_SUCCESS)  {
            if (rank == 0)
                MPI_File_delete("datafile4",MPI_INFO_NULL);
            MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_EXCL|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
        }
    } else if (delete) {
        MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_DELETE_ON_CLOSE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
        MPI_File_close(&fh);
        MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_EXCL|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
    } else {
        MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
    }

    MPI_Type_create_indexed_block(BUFSIZE, 1, map, MPI_CHAR, &filetype);
    MPI_Type_commit(&filetype);
    MPI_File_set_view(fh, disp, MPI_CHAR, filetype, "native", MPI_INFO_NULL);
    MPI_File_write_all(fh, buf, BUFSIZE, MPI_CHAR, &status);
    MPI_File_close(&fh);
    MPI_Type_free(&filetype);
    MPI_Finalize();
    return 0;
}

and running gives:

# just open CREATE|WRONLY, reproduce result above
$ mpirun -np 6 ./clobber letters none
$ cat datafile4
ABCDEFGHIJKLMNOPQRSTUVWX$
$ mpirun -np 2 ./clobber numbers none
$ cat datafile4
01234567IJKLMNOPQRSTUVWX$ 

# test for failed EXCL open, and if so, remove file:
$ mpirun -np 6 ./clobber letters test
$ cat datafile4
ABCDEFGHIJKLMNOPQRSTUVWX$
$ mpirun -np 2 ./clobber numbers test
$ cat datafile4
01234567$

# or always open delete-on-close, close, then re-open              
$ mpirun -np 6 ./clobber letters delete
$ cat datafile4
ABCDEFGHIJKLMNOPQRSTUVWX$
$ mpirun -np 2 ./clobber numbers delete
$ cat datafile4
01234567$
share|improve this answer
    
Thanks for your answer! BTW why there is a $ sign after the strings in your output file? –  Sean Aug 25 '14 at 20:46
2  
It's the prompt; there's no newline at the end of the data (which is fine in the usual use case for MPI-IO). I just hit enter after those lines or else reading it would be rather confusing. –  Jonathan Dursi Aug 25 '14 at 20:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.