#include "mpi.h"
int main( int argc, char *argv[] )
{
    int          gsizes[2], distribs[2], dargs[2], psizes[2], rank, size, m, n;
    MPI_Datatype filetype;
    int          local_array_size, num_local_rows, num_local_cols;
    int          row_procs, col_procs, row_rank, col_rank;
    MPI_File     fh; 
    float        *local_array; 
    MPI_Status   status;

    MPI_Init( &argc, &argv );

    /* ... */

    /* This code is particular to a 2 x 3 process decomposition */
    MPI_Comm_size( MPI_COMM_WORLD, &size );
    if (size != 6) {
	printf( "Communicator size must be 6\n" );
	MPI_Abort( MPI_COMM_WORLD, 1 );
    }

    /* See comments on block distribution */
    row_procs = 2;
    col_procs = 3;
    num_local_rows = (m + row_procs - 1) / row_procs;
    /* adjust for last row */
    if (row_rank == row_procs-1) 
	num_local_rows = m - (row_procs-1) * num_local_rows;
    num_local_cols = (n + col_procs - 1) / col_procs;
    /* adjust for last column */
    if (col_rank == col_procs-1) 
	num_local_cols = n - (col_procs-1) * num_local_cols;

    local_array = (float *)malloc( num_local_rows * num_local_cols * sizeof(float) );

    /* ... set elements of local_array ... */

    gsizes[0] = m;    /* no. of rows in global array */
    gsizes[1] = n;    /* no. of columns in global array*/

    distribs[0] = MPI_DISTRIBUTE_BLOCK;  /* block distribution */
    distribs[1] = MPI_DISTRIBUTE_BLOCK;  /* block distribution */

    dargs[0] = MPI_DISTRIBUTE_DFLT_DARG; /* default block size */
    dargs[1] = MPI_DISTRIBUTE_DFLT_DARG; /* default block size */

    psizes[0] = row_procs;  /* no. of processes in vertical dimension 
			       of process grid */
    psizes[1] = col_procs;  /* no. of processes in horizontal dimension 
			       of process grid */

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Type_create_darray(6, rank, 2, gsizes, distribs, dargs, 
			   psizes, MPI_ORDER_C, MPI_FLOAT, &filetype);
    MPI_Type_commit(&filetype);
    
    MPI_File_open(MPI_COMM_WORLD, "/pfs/datafile", 
		  MPI_MODE_CREATE | MPI_MODE_WRONLY, 
		  MPI_INFO_NULL, &fh);

    MPI_File_set_view(fh, 0, MPI_FLOAT, filetype, "native", 
		      MPI_INFO_NULL);

    local_array_size = num_local_rows * num_local_cols;
    MPI_File_write_all(fh, local_array, local_array_size, 
		       MPI_FLOAT, &status);
    
    MPI_File_close(&fh);

    /* ... */
    MPI_Finalize();
    return 0;
}
