/*
 * example for MPI-2 I/O :
 * 2d-array in file is distributed in column blocks
 *
 * assumes: test data in IN2, as created with create_files
 */

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include "DistMatrix.h"

#define   FILE   "IN2"
#define   SIZE   100


void check(DistMatrix a) {
  int   myId;
  int   value;
  int   i,j;

  MPI_Comm_rank(MPI_COMM_WORLD, &myId);

  for (i=0; i<a.ly; i++) {
    for (j=0; j<a.lx; j++) {
      value = 1000*i + (j + a.dx);
      if (INDEX(a,i,j) != value) {
	printf("Task %d: error in data: a(%d,%d) = %d, should be %d\n", 
	       myId, i, j, INDEX(a,i,j), value);
	return;
      }
    }
  }

  printf("Task %d: check ok\n", myId);
  return;
}

void create_array1d_type(DistMatrix a, MPI_Datatype *array1d_type) {
  /* creates type for file view  */

  int  size, length, offset;

  size   = a.nx;
  length = a.lx;
  offset = a.dx;
  MPI_Type_create_subarray(1, &size, &length, &offset, MPI_ORDER_C, 
                            MPI_INT, array1d_type); 

  MPI_Type_commit(array1d_type);
}


void main(int argc, char *argv[]) {
  MPI_File       fh;
  MPI_Datatype   fileType;
  MPI_Status     status;
  DistMatrix     a;

  MPI_Init(&argc, &argv);
  newDistMatrix(&a, SIZE, SIZE);
  create_array1d_type(a, &fileType);

  MPI_File_open(MPI_COMM_WORLD, FILE, MPI_MODE_RDONLY, MPI_INFO_NULL, &fh); 
  MPI_File_set_view(fh, 0, MPI_INT, fileType, "native", MPI_INFO_NULL); 

  MPI_File_read_all(fh, a.data, a.lx*a.ly, MPI_INT, &status); 

  check(a);

  MPI_File_close(&fh);
  MPI_Finalize();
}