/*
* example for MPI-2 I/O :
* node data (f.i. molecular dynamics application) is dumped
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define FILENAME "OUT1"
#define SIZE 100
typedef struct {
int id, host;
double xPos, yPos;
double m;
} Particle;
void init(Particle *p) {
/* initialize particle array */
int myId;
int i;
MPI_Comm_rank(MPI_COMM_WORLD, &myId);
for (i=0; i<SIZE; i++) {
p[i].id = i;
p[i].host = myId;
p[i].xPos = 1.0 + myId;
p[i].yPos = 42.0 * i;
p[i].m = 17 + 4*i - myId;
}
}
void check(void) {
/* master reads back particle file and checks data */
Particle in, test;
FILE *fp;
int myId, nTasks;
int i, id, host;
MPI_Comm_size(MPI_COMM_WORLD, &nTasks);
MPI_Comm_rank(MPI_COMM_WORLD, &myId);
if (myId != 0) {
return;
}
fp = fopen(FILENAME, "r");
for (i=0; i<SIZE*nTasks; i++) {
if (fread(&in, sizeof(Particle), 1, fp) != 1) {
printf("error during file read at index i = %d\n", i);
return;
}
test.id = in.id;
test.host = in.host;
test.xPos = 1.0 + in.host;
test.yPos = 42 * in.id;
test.m = 17 + 4*in.id - in.host;
if ( (test.xPos != in.xPos) || (test.yPos != in.yPos) ||
(test.m != in.m) ) {
printf("error in data: \n");
printf("read : (%d,%d,%lf,%lf,%lf)\n",
in.id, in.host, in.xPos, in.yPos, in.m);
printf("should be: (%d,%d,%lf,%lf,%lf)\n",
test.id, test.host, test.xPos, test.yPos, test.m);
return;
}
}
fclose(fp);
printf("check ok\n");
return;
}
void create_pType(MPI_Datatype *pType) {
/* creates type for particle */
int blocks[3] = {1, 1, 3};
MPI_Datatype types[3] = {MPI_INT, MPI_INT, MPI_DOUBLE};
MPI_Aint disps[3] = {0, 8, 16};
MPI_Type_struct(3, blocks, disps, types, pType);
MPI_Type_commit(pType);
}
void main(int argc, char *argv[]) {
MPI_File fh;
MPI_Datatype pType;
MPI_Status status;
Particle p[SIZE];
MPI_Init(&argc, &argv);
init(p);
create_pType(&pType);
MPI_File_open(MPI_COMM_WORLD, FILENAME, MPI_MODE_WRONLY|MPI_MODE_CREATE,
MPI_INFO_NULL, &fh);
MPI_File_set_view(fh, 0, pType, pType, "native", MPI_INFO_NULL);
MPI_File_write_ordered(fh, p, SIZE, pType, &status);
MPI_File_close(&fh);
check();
MPI_Finalize();
}