Exemple #1
0
int main(int argc, char **argv)
{
    int *buf, i, rank, nints, len;
    char *filename, *tmp;
    int errs=0, toterrs;
    MPI_File fh;
    MPI_Status status[NR_NBOPS];
    MPI_Request request[NR_NBOPS];
    int errcode = 0;

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

/* process 0 takes the file name as a command-line argument and
   broadcasts it to other processes */
    if (!rank) {
	i = 1;
	while ((i < argc) && strcmp("-fname", *argv)) {
	    i++;
	    argv++;
	}
	if (i >= argc) {
	    fprintf(stderr, "\n*#  Usage: async -fname filename\n\n");
	    MPI_Abort(MPI_COMM_WORLD, 1);
	}
	argv++;
	len = strlen(*argv);
	filename = (char *) malloc(len+10);
	strcpy(filename, *argv);
	MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
	MPI_Bcast(filename, len+10, MPI_CHAR, 0, MPI_COMM_WORLD);
    }
    else {
	MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
	filename = (char *) malloc(len+10);
	MPI_Bcast(filename, len+10, MPI_CHAR, 0, MPI_COMM_WORLD);
    }


    buf = (int *) malloc(SIZE);
    nints = SIZE/sizeof(int);
    for (i=0; i<nints; i++) buf[i] = rank*100000 + i;

    /* each process opens a separate file called filename.'myrank' */
    tmp = (char *) malloc(len+10);
    strcpy(tmp, filename);
    sprintf(filename, "%s.%d", tmp, rank);

    errcode = MPI_File_open(MPI_COMM_SELF, filename,
		    MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
    if (errcode != MPI_SUCCESS) {
	    handle_error(errcode, "MPI_File_open");
    }
    MPI_File_set_view(fh, 0, MPI_INT, MPI_INT, "native", MPI_INFO_NULL);
    for (i=0; i<NR_NBOPS; i++) {
	errcode = MPI_File_iwrite_at(fh, nints/NR_NBOPS*i,
		buf+(nints/NR_NBOPS*i), nints/NR_NBOPS, MPI_INT, &(request[i]));
	if (errcode != MPI_SUCCESS) {
	    handle_error(errcode, "MPI_File_iwrite");
	}
    }
    MPI_Waitall(NR_NBOPS, request, status);

    MPI_File_close(&fh);

    /* reopen the file and read the data back */

    for (i=0; i<nints; i++) buf[i] = 0;
    errcode = MPI_File_open(MPI_COMM_SELF, filename,
		    MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
    if (errcode != MPI_SUCCESS) {
	    handle_error(errcode, "MPI_File_open");
    }

    MPI_File_set_view(fh, 0, MPI_INT, MPI_INT, "native", MPI_INFO_NULL);
    for (i=0; i<NR_NBOPS; i++) {
	errcode = MPI_File_iread_at(fh, nints/NR_NBOPS*i,
		buf+(nints/NR_NBOPS*i), nints/NR_NBOPS, MPI_INT, &(request[i]));
	if (errcode != MPI_SUCCESS) {
	    handle_error(errcode, "MPI_File_open");
	}
    }
    MPI_Waitall(NR_NBOPS, request, status);

    MPI_File_close(&fh);

    /* check if the data read is correct */
    for (i=0; i<nints; i++) {
	if (buf[i] != (rank*100000 + i)) {
	    errs++;
	    fprintf(stderr, "Process %d: error, read %d, should be %d\n", rank, buf[i], rank*100000+i);
	}
    }

    MPI_Allreduce( &errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
    if (rank == 0) {
	if( toterrs > 0) {
	    fprintf( stderr, "Found %d errors\n", toterrs );
	}
	else {
	    fprintf( stdout, " No Errors\n" );
	}
    }

    free(buf);
    free(filename);
    free(tmp);

    MPI_Finalize();
    return 0;
}
Exemple #2
0
PetscErrorCode VecView_Seq_Binary(Vec xin,PetscViewer viewer)
{
  PetscErrorCode    ierr;
  int               fdes;
  PetscInt          n = xin->map->n,classid=VEC_FILE_CLASSID;
  FILE              *file;
  const PetscScalar *xv;
#if defined(PETSC_HAVE_MPIIO)
  PetscBool         isMPIIO;
#endif
  PetscBool         skipHeader;
  PetscViewerFormat format;

  PetscFunctionBegin;
  /* Write vector header */
  ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
  if (!skipHeader) {
    ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
    ierr = PetscViewerBinaryWrite(viewer,&n,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
  }

  /* Write vector contents */
#if defined(PETSC_HAVE_MPIIO)
  ierr = PetscViewerBinaryGetUseMPIIO(viewer,&isMPIIO);CHKERRQ(ierr);
  if (!isMPIIO) {
#endif
    ierr = PetscViewerBinaryGetDescriptor(viewer,&fdes);CHKERRQ(ierr);
    ierr = VecGetArrayRead(xin,&xv);CHKERRQ(ierr);
    ierr = PetscBinaryWrite(fdes,(void*)xv,n,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
    ierr = VecRestoreArrayRead(xin,&xv);CHKERRQ(ierr);
    ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
    if (format == PETSC_VIEWER_BINARY_MATLAB) {
      MPI_Comm   comm;
      FILE       *info;
      const char *name;

      ierr = PetscObjectGetName((PetscObject)xin,&name);CHKERRQ(ierr);
      ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
      ierr = PetscViewerBinaryGetInfoPointer(viewer,&info);CHKERRQ(ierr);
      ierr = PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr);
      ierr = PetscFPrintf(comm,info,"#$$ Set.%s = PetscBinaryRead(fd);\n",name);CHKERRQ(ierr);
      ierr = PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr);
    }
#if defined(PETSC_HAVE_MPIIO)
  } else {
    MPI_Offset   off;
    MPI_File     mfdes;
    PetscMPIInt  lsize;

    ierr = PetscMPIIntCast(n,&lsize);CHKERRQ(ierr);
    ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr);
    ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr);
    ierr = MPI_File_set_view(mfdes,off,MPIU_SCALAR,MPIU_SCALAR,(char*)"native",MPI_INFO_NULL);CHKERRQ(ierr);
    ierr = VecGetArrayRead(xin,&xv);CHKERRQ(ierr);
    ierr = MPIU_File_write_all(mfdes,(void*)xv,lsize,MPIU_SCALAR,MPI_STATUS_IGNORE);CHKERRQ(ierr);
    ierr = VecRestoreArrayRead(xin,&xv);CHKERRQ(ierr);
    ierr = PetscViewerBinaryAddMPIIOOffset(viewer,n*sizeof(PetscScalar));CHKERRQ(ierr);
  }
#endif

  ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr);
  if (file) {
    if (((PetscObject)xin)->prefix) {
      ierr = PetscFPrintf(PETSC_COMM_SELF,file,"-%svecload_block_size %D\n",((PetscObject)xin)->prefix,PetscAbs(xin->map->bs));CHKERRQ(ierr);
    } else {
      ierr = PetscFPrintf(PETSC_COMM_SELF,file,"-vecload_block_size %D\n",PetscAbs(xin->map->bs));CHKERRQ(ierr);
    }
  }
  PetscFunctionReturn(0);
}
Exemple #3
0
int main(int argc, char *argv[]) {

  int my_id, nprocs;
  int mpi_dims[4]; 
  int period[4] = {0, 0, 0, 0};
  int coords[4];

  int dimsf[4] = {nbands, gpts, gpts, gpts};
  int count[4];
  int offset[4];
  int ndims = 4;

  double t0, t1;
#ifdef PAPI
  PAPI_dmem_info_t dmem;
  double mem1, mem2, mem1_max, mem2_max, mem1_ave, mem2_ave;
  int papi_err;
#endif

  double *my_data;

  MPI_Comm cart_comm;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

  assert(argc == 5);
  for (int i=1; i < argc; i++)
    mpi_dims[i-1] = atoi(argv[i]);

  assert(mpi_dims[0] * mpi_dims[1] * mpi_dims[2] * mpi_dims[3] == nprocs);
  MPI_Cart_create(MPI_COMM_WORLD, 4, mpi_dims, period, 0, &cart_comm);
  MPI_Comm_rank(cart_comm, &my_id);

  MPI_Cart_coords(cart_comm, my_id, 4, coords);

  assert(nbands % mpi_dims[0] == 0);
  for (int i=1; i < 4; i++)
    assert(gpts % mpi_dims[i] == 0);

  int total_size = nbands*gpts*gpts*gpts;
  count[0] = nbands / mpi_dims[0];
  offset[0] = coords[0] * count[0];
  int data_size = count[0];
  for (int i=1; i < 4; i++)
    {
      count[i] = gpts/mpi_dims[i];
      offset[i] = coords[i] * count[i];
      data_size *= count[i];
    }

  my_data = (double *) malloc(data_size * sizeof(double));
  for (int i=0; i < data_size; i++)
    my_data[i] = my_id;

  MPI_Info info;
  MPI_File fp;
  MPI_Datatype filetype;
  // MPI_Info_set(info, "cb_nodes", "64");

  MPI_Barrier(MPI_COMM_WORLD);
#ifdef PAPI
  papi_err = PAPI_get_dmem_info(&dmem);
  if (papi_err != PAPI_OK)
    printf("PAPI_ERR\n");
  mem1 = (double)dmem.size / 1024.0;
  MPI_Reduce(&mem1, &mem1_max, 1, MPI_DOUBLE, MPI_MAX, 0, cart_comm);
  MPI_Reduce(&mem1, &mem1_ave, 1, MPI_DOUBLE, MPI_SUM, 0, cart_comm);
  mem1_ave /= nprocs;
#endif
  t0 = MPI_Wtime();
  MPI_File_open(MPI_COMM_WORLD, "test.dat",
                  MPI_MODE_CREATE|MPI_MODE_WRONLY,
                  MPI_INFO_NULL, &fp);

  MPI_Type_create_subarray(ndims, dimsf, count, offset, MPI_ORDER_C, 
			   MPI_DOUBLE, &filetype);
  MPI_Type_commit(&filetype);
  MPI_File_set_view(fp, 0, MPI_DOUBLE, filetype, "native", MPI_INFO_NULL);

  MPI_File_write_all(fp, my_data, data_size, MPI_DOUBLE, MPI_STATUS_IGNORE);

  MPI_Type_free(&filetype);
  MPI_File_close(&fp);
  MPI_Barrier(MPI_COMM_WORLD);
  t1 = MPI_Wtime();
#ifdef PAPI
  papi_err = PAPI_get_dmem_info(&dmem);
  if (papi_err != PAPI_OK)
    printf("PAPI_ERR\n");
  mem2 = (double)dmem.size/ 1024.0;
  MPI_Reduce(&mem2, &mem2_max, 1, MPI_DOUBLE, MPI_MAX, 0, cart_comm);
  MPI_Reduce(&mem2, &mem2_ave, 1, MPI_DOUBLE, MPI_SUM, 0, cart_comm);
  mem2_ave /= nprocs;
#endif
  if (my_id == 0)
    {
      printf("IO time %f (%f) MB %f s\n", 
             total_size * 8/(1024.0*1024.0), 
             data_size * 8/(1024.0*1024.0), t1-t0);
#ifdef PAPI
      printf("Memory usage max (ave): %f (%f) %f (%f) \n", 
              mem1_max, mem1_ave, mem2_max, mem2_ave);
#endif
    }
      
  MPI_Finalize();
}
Exemple #4
0
static int test_mpio_derived_dtype(char *filename) {

    MPI_File fh;
    char mpi_err_str[MPI_MAX_ERROR_STRING];
    int  mpi_err_strlen;
    int  mpi_err;
    int  i;
    int  nerrors = 0;    /* number of errors */
    MPI_Datatype  etype,filetype;
    MPI_Datatype  adv_filetype,bas_filetype[2];
    MPI_Datatype  etypenew, filetypenew;
    MPI_Offset    disp;
    MPI_Status    Status;
    MPI_Aint      adv_disp[2];
    MPI_Aint      offsets[1];
    int           blocklens[1],adv_blocklens[2];
    int           count,outcount;
    int           retcode;

    int mpi_rank,mpi_size;

    char          buf[3],outbuf[3] = {0};

    MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
    retcode = 0;
    for(i=0;i<3;i++)
      buf[i] = i+1;


    if ((mpi_err = MPI_File_open(MPI_COMM_WORLD, filename,
         MPI_MODE_RDWR | MPI_MODE_CREATE,
         MPI_INFO_NULL, &fh))
      != MPI_SUCCESS){
  MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_File_open failed (%s)\n", mpi_err_str);
  return 1;
    }

    disp  = 0;
    etype = MPI_BYTE;

    count = 1;
    blocklens[0] = 1;
    offsets[0]   = 0;

    if((mpi_err= MPI_Type_hindexed(count,blocklens,offsets,MPI_BYTE,&filetype))
       != MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_Type_contiguous failed (%s)\n", mpi_err_str);
  return 1;
    }

    if((mpi_err=MPI_Type_commit(&filetype))!=MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
  return 1;
    }

    count = 1;
    blocklens[0]=1;
    offsets[0] = 1;
    if((mpi_err= MPI_Type_hindexed(count,blocklens,offsets,MPI_BYTE,&filetypenew))
       != MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_Type_contiguous failed (%s)\n", mpi_err_str);
  return 1;
    }

    if((mpi_err=MPI_Type_commit(&filetypenew))!=MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
  return 1;
    }

    outcount         = 2;
    adv_blocklens[0] = 1;
    adv_blocklens[1] = 1;
    adv_disp[0]      = 0;
    adv_disp[1]      = 1;
    bas_filetype[0]  = filetype;
    bas_filetype[1]  = filetypenew;

    if((mpi_err= MPI_Type_struct(outcount,adv_blocklens,adv_disp,bas_filetype,&adv_filetype))
       != MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_Type_struct failed (%s)\n", mpi_err_str);
  return 1;
    }
    if((mpi_err=MPI_Type_commit(&adv_filetype))!=MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
  return 1;
    }


    if((mpi_err = MPI_File_set_view(fh,disp,etype,adv_filetype,"native",MPI_INFO_NULL))!= MPI_SUCCESS){
      MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_File_set_view failed (%s)\n", mpi_err_str);
  return 1;
    }

    if((mpi_err = MPI_File_write(fh,buf,3,MPI_BYTE,&Status))!= MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_File_write failed (%s)\n", mpi_err_str);
  return 1;
      ;
    }


    if((mpi_err = MPI_File_close(&fh)) != MPI_SUCCESS){
       MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_File_close failed (%s)\n", mpi_err_str);
  return 1;
    }


    if((mpi_err = MPI_File_open(MPI_COMM_WORLD,filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&fh)) != MPI_SUCCESS){
       MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_File_open failed (%s)\n", mpi_err_str);
  return 1;
    }

    if((mpi_err = MPI_File_set_view(fh,0,MPI_BYTE,MPI_BYTE,"native",MPI_INFO_NULL))!= MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_File_set_view failed (%s)\n", mpi_err_str);
  return 1;
    }
    if((mpi_err = MPI_File_read(fh,outbuf,3,MPI_BYTE,&Status))!=MPI_SUCCESS){
      MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
      printf("MPI_File_read failed (%s)\n", mpi_err_str);
      return 1;
    }

    if(outbuf[2]==2) {
       retcode = 0;
    }
    else {
/*      if(mpi_rank == 0) {
       printf("complicated derived datatype is NOT working at this platform\n");
       printf("go back to hdf5/config and find the corresponding\n");
       printf("configure-specific file and change ?????\n");
      }
*/
       retcode = -1;
   }

    if((mpi_err = MPI_File_close(&fh)) != MPI_SUCCESS){
       MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
  printf("MPI_File_close failed (%s)\n", mpi_err_str);
  return 1;
    }


    mpi_err = MPI_Barrier(MPI_COMM_WORLD);
    if(retcode == -1) {
	if(mpi_rank == 0) {
	    printf("Complicated derived datatype is NOT working at this platform\n");
	    printf(" Please report to [email protected] about this problem.\n");
	}
	retcode = 1;
    }
    return retcode;
}
void IOserver::start()
{
    //starting IO server (Sinc line)
    
    MPI_Status status,status2;
    MPI_Request send_statut_request;
    int flag=1;
    int control;
    
    int count=0;
    int fileID;
    int fileCounter;
    int newFilenameLength;
    int len;
    bool getingDataFlag;
    int getingData[IO_ClientSize_];
    
    
    
    
    serverOn_flag=true;
    
    while(serverOn_flag)
    {
        //cout<<count<<endl;
        
        
        ostreamFile_flag=false;
        
        if(IO_Rank_==0)
        {
            //cout<<count<<endl;
            //count++;
            
            //send non-blocking for status server free. (Sync line)
            
            serverReady_flag=true;
            MPI_Isend(&serverReady_flag,1,MPI::BOOL,1,SERVER_STATE_TAG,syncLineComm_,&send_statut_request);
        
            //test if an ostream need to be open or if the server need to be stoped (Sync line) blocking rec
      
            MPI_Recv(&control,1,MPI::INT,1,SERVER_CONTROL_TAG,syncLineComm_,&status);            
        }
        
        MPI_Bcast(&control,1,MPI::INT,0,IO_Comm_);
        //MPI_Bcast(&ostreamFile_flag,1,MPI::BOOL,0,IO_Comm_);
        
        if(control==CONTROL_STOP)
        {
            //if(IO_Rank_==0)cout<<"stop server"<<endl;
            serverOn_flag=false;
        }
        if(control==CONTROL_OPEN_OSTREAM)
        {
            //if(IO_Rank_==0)cout<<"ostream"<<endl;
            ostreamFile_flag=true;
            serverReady_flag=false;
            if(IO_Rank_==0)MPI_Isend(&serverReady_flag,1,MPI::BOOL,1,SERVER_STATE_TAG,syncLineComm_,&send_statut_request);
            fileCounter=0;
            
            
            while(ostreamFile_flag)
            {
                //cout<<"rank: "<<IO_Rank_<<", ostream open"<<endl;
                
                //test if there is a new file (Sync line)
                
                
                
                if(IO_Rank_==0)MPI_Recv(&control,1,MPI::INT,1,IO_FILE_CONTROL_TAG,syncLineComm_,&status);
                
                MPI_Bcast(&control,1,MPI::INT,0,IO_Comm_);
                
                if(control==CONTROL_CLOSE_OSTREAM)
                {
                    //if(IO_Rank_==0)cout<<"stop ostream"<<endl;
                    ostreamFile_flag=false;
                }
                
                if(control==CONTROL_CREATE_FILE)
                {
                    //create new file ID
                    if(fileCounter>= MAX_FILE_NUMBER)
                    {
                        if(IO_Rank_==0)cout<<"Already to much file"<<endl;
                        fileID=FILE_FAIL;
                    }
                    else
                    {
                        fileID=fileCounter;
                        
                        //if(IO_Rank_==0)cout<<"IO_server creating new file : "<<fileID<<endl;
                    }
                    
                    if(IO_Rank_==0)MPI_Ssend(&fileID,1,MPI::INT,1,IO_FILE_CONTROL_FILEID_TAG,syncLineComm_);
                    if(fileID  != FILE_FAIL)
                    {
                        if(IO_Rank_==0)
                        {
                            MPI_Probe(1,IO_FILE_CONTROL_FILENAME_TAG,syncLineComm_,&status);
                            MPI_Get_count(&status,MPI::CHAR,&newFilenameLength);
                        }
                        MPI_Bcast(&newFilenameLength,1,MPI::INT,0,IO_Comm_);
                        char * filename;
                        filename = (char*)malloc(newFilenameLength*sizeof(char));
                        if(IO_Rank_==0)MPI_Recv(filename,newFilenameLength,MPI::CHAR,1,IO_FILE_CONTROL_FILENAME_TAG,syncLineComm_,&status2);
                        MPI_Bcast(filename,newFilenameLength,MPI::CHAR,0,IO_Comm_);
                        files[fileID].filename=filename;
                        free(filename);
                        files[fileID].type=FILETYPE_UNSTRUCTURED; // no structured file implemented!!!!
                        //cout<< files[fileID].filename <<endl;
                        
                        if(fileID==0)files[fileID].data=dataBuffer;
                        else files[fileID].data=&(files[fileID-1].data[files[fileID-1].size]);
                        
                        files[fileID].size=0;
                        
                        fileCounter++;
                        
                        
                        if(files[fileID].type==FILETYPE_UNSTRUCTURED)
                        {
                            for(int i=0;i<IO_ClientSize_;i++)getingData[i]=1;
                            getingDataFlag=true;
                            
                            
                            while(getingDataFlag)
                            {
                                MPI_Iprobe(MPI_ANY_SOURCE,fileID, masterClientComm_,&flag,&status);
                                if(flag==true)
                                {
                                    char * send;
                                    send=&(files[fileID].data[files[fileID].size]);
                                    int size;
                                    MPI_Get_count(&status,MPI::CHAR,&size);
                                    MPI_Recv(send,size,MPI::CHAR,status.MPI_SOURCE,fileID,masterClientComm_,&status2);
                                    files[fileID].size+=size;
                                }
                                else
                                {
                                    MPI_Iprobe(MPI_ANY_SOURCE,IO_FILE_CONTROL_CLOSE_TAG,masterClientComm_ ,&flag,&status);
                                    if(flag==true)
                                    {
                                        //cout<<"file closed"<<endl;  
                                        int tempFileID;
                                        int total=0;
                                        int source = status.MPI_SOURCE;
                                        //cout<<source<<endl;
                                        MPI_Recv(&tempFileID,1,MPI::INT,source,IO_FILE_CONTROL_CLOSE_TAG,masterClientComm_,&status2);
                                        //cout<<source<<endl;
                                        getingData[source-1]=0;
                                        for(int i=0;i<IO_ClientSize_;i++)total+=getingData[i];
                                        if(total==0)getingDataFlag=false;
                                        //cout<<total<<endl;
                                    }
                                    
                                }
                            }
                            //cout<<"file closed"<<endl;
                            MPI_Barrier(IO_Comm_);
                        }
                        MPI_Barrier(IO_Comm_);
                        
                        
                        
                    }
                    
                }
                
            }//close stream and write

            
            
            if(fileCounter!=0)
            {
                for(int i=0;i < fileCounter;i++)
                {
                    //cout<<"writing file: "<< i<<endl;
                    
                    MPI_File ofile;
                    
                    long file_Offset=0;
                    long temp_long=0;
                    string str_fname;
                    str_fname = files[i].filename + int2string(IO_Node_,999)+".dat";
                    char * fname = &(str_fname[0]);
                    
                    for(int k=0;k<(IO_NodeSize_-1); k++)
                    {
                        if(IO_NodeRank_==k)
                        {
                            temp_long = file_Offset + files[i].size;
                            MPI_Send(&temp_long,1,MPI_LONG, k+1 , 0, IO_NodeComm_ );
                        }
                        if(IO_NodeRank_==k+1)
                        {
                            MPI_Recv( &file_Offset, 1, MPI_LONG, k, 0, IO_NodeComm_, &status);
                        }
                    }
                    
                    if(files[i].size!=0)
                    {
                        MPI_File_open(IO_NodeComm_,fname,MPI_MODE_WRONLY | MPI_MODE_CREATE,MPI_INFO_NULL,&ofile);
                        MPI_File_set_view(ofile,file_Offset,MPI_CHAR,MPI_CHAR,(char*)"native",MPI_INFO_NULL);
                        MPI_File_write_all(ofile,files[i].data,files[i].size,MPI_CHAR,&status);
                        MPI_File_close(&ofile);
                    } 
                }
            }
            fileCounter=0;
            
            MPI_Barrier(IO_Comm_);
        
        
        }
        
        
                

        
    }
}
Exemple #6
0
int main( int argc, char *argv[] )
{
  int opt;
  extern char   *optarg;
  extern int     optind;
  int is_output_timing=0, is_print_usage = 0;
  int _debug=0, use_gen_file = 0, use_actsto = 0, use_normalsto=0;
  char *token;

  MPI_Offset disp, offset, file_size;
  MPI_Datatype etype, ftype, buftype;

  int errs = 0;
  int size, rank, i, count;
  char *fname = NULL;
  double *buf;
  MPI_File fh;
  MPI_Comm comm;
  MPI_Status status;
  int64_t nitem = 0;
  int fsize = 0, type_size;
  double stime, etime, iotime, comptime, elapsed_time;
  double max_iotime, max_comptime;

  double max, min, sum=0.0, global_sum;

  MPI_Init( &argc, &argv );
 
  comm = MPI_COMM_WORLD;

  MPI_Comm_size( comm, &size );
  MPI_Comm_rank( comm, &rank );
 
  while ( (opt=getopt(argc,argv,"i:s:godhxt"))!= EOF) {
    switch (opt) {
    case 'i': fname = optarg;
      break;
    case 'o': is_output_timing = 1;
      break;
    case 'g': use_gen_file = 1;
      break;
    case 'd': _debug = 1;
      break;
    case 'h': is_print_usage = 1;
      break;
    case 's': 
        token = strtok(optarg, ":");
        //if (rank == 0) printf("token=%s\n", token);
        if(token == NULL) {
            if (rank == 0) printf("1: Wrong file size format!\n");
            MPI_Finalize();
            exit(1);
        }

        fsize = atoi(token);
        token = strtok(NULL, ":");
        //if (rank == 0) printf("token=%s\n", token);
        if(token == NULL) {
            if (rank == 0) printf("2: Wrong file size format!\n");
            MPI_Finalize();
            exit(1);
        }
        if(*token != 'm' && *token != 'g') {
            if (rank == 0) printf("3: Wrong file size format!\n");
            MPI_Finalize();
            exit(1);
        }
        if (rank ==0) printf("fsize = %d (%s)\n", fsize, (*token=='m'?"MB":"GB"));
      if (fsize == 0)
	nitem = 0;
      else {
	MPI_Type_size(MPI_DOUBLE, &type_size);
	nitem = fsize*1024; /* KB */
	nitem = nitem*1024; /* MB */
        if(*token == 'g') {
            //if(rank == 0) printf("data in GB\n");
            nitem = nitem*1024; /* GB */
        }
	nitem = nitem/type_size;
	//printf("nitem=%lld\n", nitem);
	nitem = nitem/size; /* size means comm size */
      }
      if (rank == 0) printf("nitem = %d\n", nitem);
      break;
    case 'x': use_actsto = 1;
      break;
    case 't': use_normalsto = 1;
      break;
    default: is_print_usage = 1;
      break;
    }
  }

  if (fname == NULL || is_print_usage == 1 || nitem == 0) {
    if (rank == 0) usage(argv[0]);
    MPI_Finalize();
    exit(1);
  }

  int sizeof_mpi_offset;
  sizeof_mpi_offset = (int)(sizeof(MPI_Offset)); // 8 
  //if (rank == 0) printf ("size_of_mpi_offset=%d\n", sizeof_mpi_offset);

  if(use_normalsto == 1 && use_actsto == 1) {
      if(rank == 0)
          printf("Can't test both: either normalsto or actsto\n");
      MPI_Finalize();
      exit(1);
  }
#if 0
  if(use_actsto == 1) {
      if (size != 1) {
          if(rank == 0)
              printf("active storage should be run with only 1 process!!!\n");
          MPI_Finalize();
          exit(1);
      }
  }
#endif
  /* initialize random seed: */
  srand(time(NULL));

  if(use_gen_file == 1) {
    int t, result;

    MPI_File_open( comm, fname, MPI_MODE_RDWR | MPI_MODE_CREATE, MPI_INFO_NULL, &fh );

    /* Set the file view */
    disp = rank * nitem * type_size;
    printf("%d: disp = %lld\n", rank, disp);
    etype = MPI_DOUBLE;
    ftype = MPI_DOUBLE;

    result = MPI_File_set_view(fh, disp, etype, ftype, "native", MPI_INFO_NULL);

    if(result != MPI_SUCCESS) 
      sample_error(result, "MPI_File_set_view");

    buf = (double *)malloc( nitem * sizeof(double) );

    if (buf == NULL) {
        if(rank == 0) printf("malloc() failed\n");
        MPI_Finalize();
        exit(1);
    }

    buf[0] = rand()%4096;
    if(rank==0) printf("%lf\n", buf[0]);
    max = min = sum = buf[0];

    for(i=1; i<nitem; i++) {
      t = rand()%4096;
      if (t>max) max = t;
      if (t<min) min = t;
      sum += t;
      buf[i] = t;
      if (i<10 && rank == 0) printf("%lf\n", buf[i]);
    }
    
    if(rank == 0) {
      printf("MPI_Type_size(MPI_DOUBLE)=%d\n", type_size);
      printf ("max=%lf, min=%lf, sum=%lf\n", max, min, sum);
    }

    stime = MPI_Wtime();
    /* Write to file */
    MPI_File_write_all( fh, buf, nitem, MPI_DOUBLE, &status );
    etime = MPI_Wtime();
    iotime = etime - stime;
      
    printf("%d: iotime (write) = %10.4f\n", rank, iotime);

    MPI_Get_count( &status, MPI_DOUBLE, &count );
    //printf("count = %lld\n", count);

    if (count != nitem) {
      fprintf( stderr, "%d: Wrong count (%lld) on write\n", rank, count );
      fflush(stderr);
      /* exit */
      MPI_Finalize();
      exit(1);
    }

    MPI_File_close(&fh);
    MPI_Barrier(MPI_COMM_WORLD);
    if(rank == 0) printf("File is written\n\n");
  }

  double *tmp = (double *)malloc( nitem * sizeof(double) );
  memset (tmp, 0, nitem*sizeof(double));

  if(use_normalsto == 1) {
      MPI_File_open( comm, fname, MPI_MODE_RDWR, MPI_INFO_NULL, &fh );
      /* Read nothing (check status) */
      memset( &status, 0xff, sizeof(MPI_Status) );
      
      offset = rank * nitem * type_size;

      /* start I/O */
      stime = MPI_Wtime();
      MPI_File_read_at(fh, offset, tmp, nitem, MPI_DOUBLE, &status);
      etime = MPI_Wtime();
      /* end I/O */
      iotime = etime - stime;
      
      if(_debug==1) printf("%d: iotime = %10.4f\n", rank, iotime);
      MPI_Reduce(&iotime, &max_iotime, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
      
      sum = 0.0; /* reset sum */
      
      /* start computation */
      stime = MPI_Wtime();
      
      for(i=0; i<nitem; i++) {
          sum += tmp[i];
      }
      
      MPI_Reduce(&sum, &global_sum, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
      etime = MPI_Wtime();
      /* end computation */

      comptime = etime - stime;

      if(_debug==1) printf("%d: comptime = %10.4f\n", rank, comptime);
      
      MPI_Reduce(&comptime, &max_comptime, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);

      if(rank == 0) {
          elapsed_time = max_comptime + max_iotime;
          printf("<<Result (SUM) with normal read>>\n"
                 "SUM              = %10.4f \n"
                 "Computation time = %10.4f sec\n"
                 "I/O time         = %10.4f sec\n"
                 "total time       = %10.4f sec\n\n", 
                 global_sum, max_comptime, max_iotime, elapsed_time);
      }
      
      MPI_File_close(&fh);
  }
#if 0
  if(use_actsto == 1) {
#if 0
    /* MPI_MAX */
    MPI_File_open( comm, fname, MPI_MODE_RDWR, MPI_INFO_NULL, &fh );

    stime = MPI_Wtime();
    MPI_File_read_at_ex( fh, offset, tmp, nitem, MPI_DOUBLE, MPI_MAX, &status );
    etime = MPI_Wtime();
    elapsed_time = etime-stime;
    printf ("<<Result with active storage>>\n"
	    "max=%lf (in %10.4f sec)\n", tmp[0], elapsed_time);
    
    MPI_File_close(&fh);
    
    /* MPI_MIN */
    MPI_File_open( comm, fname, MPI_MODE_RDWR, MPI_INFO_NULL, &fh );
    
    stime = MPI_Wtime();
    MPI_File_read_at_ex( fh, offset, tmp, nitem, MPI_DOUBLE, MPI_MIN, &status );
    etime = MPI_Wtime();
    elapsed_time = etime - stime;
    printf ("min=%lf (in %10.4f sec)\n", tmp[0], elapsed_time); 
    
    MPI_File_close(&fh);
#endif

    /* MPI_SUM */
    MPI_File_open( comm, fname, MPI_MODE_RDWR, MPI_INFO_NULL, &fh );
    memset(&status, 0xff, sizeof(MPI_Status));
    offset = rank * nitem * type_size;
    
    stime = MPI_Wtime();
    MPI_File_read_at_ex( fh, offset, tmp, nitem, MPI_DOUBLE, MPI_SUM, &status );
    etime = MPI_Wtime();
    elapsed_time = etime - stime;
    printf ("<<Result with active storage>>\n"
            "sum=%lf (in %10.4f sec)\n", tmp[0], elapsed_time); 
    
    MPI_File_close( &fh );
  }
#endif
  MPI_Barrier(MPI_COMM_WORLD);
  if (use_gen_file == 1) free( buf );
  free( tmp );
 
  MPI_Finalize();
  return errs;
}
int test_file(char *filename, int mynod, int nprocs, char * cb_hosts, char *msg, int verbose) 
{
    MPI_Datatype typevec, newtype, t[3];
    int *buf, i, b[3], errcode, errors=0;
    MPI_File fh;
    MPI_Aint d[3];
    MPI_Status status;
    int SIZE = (STARTING_SIZE/nprocs)*nprocs;
    MPI_Info info;

    if (mynod==0 && verbose) fprintf(stderr, "%s\n", msg);

    buf = (int *) malloc(SIZE*sizeof(int));
    if (buf == NULL) {
	    perror("test_file");
	    MPI_Abort(MPI_COMM_WORLD, -1);
    }


    if (cb_hosts != NULL ) {
	    MPI_Info_create(&info);
	    MPI_Info_set(info, "cb_config_list", cb_hosts);
    } else {
	    info = MPI_INFO_NULL;
    }

    MPI_Type_vector(SIZE/nprocs, 1, nprocs, MPI_INT, &typevec);

    b[0] = b[1] = b[2] = 1;
    d[0] = 0;
    d[1] = mynod*sizeof(int);
    d[2] = SIZE*sizeof(int);
    t[0] = MPI_LB;
    t[1] = typevec;
    t[2] = MPI_UB;

    MPI_Type_struct(3, b, d, t, &newtype);
    MPI_Type_commit(&newtype);
    MPI_Type_free(&typevec);

    if (!mynod) {
	if(verbose) fprintf(stderr, "\ntesting noncontiguous in memory, noncontiguous in file using collective I/O\n");
	MPI_File_delete(filename, info);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    errcode = MPI_File_open(MPI_COMM_WORLD, filename, 
		    MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh);
    if (errcode != MPI_SUCCESS) {
	    handle_error(errcode, "MPI_File_open");
    }

    MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);

    for (i=0; i<SIZE; i++) buf[i] = SEEDER(mynod,i,SIZE);
    errcode = MPI_File_write_all(fh, buf, 1, newtype, &status);
    if (errcode != MPI_SUCCESS) {
	    handle_error(errcode, "nc mem - nc file: MPI_File_write_all");
    }

    MPI_Barrier(MPI_COMM_WORLD);

    for (i=0; i<SIZE; i++) buf[i] = -1;

    errcode = MPI_File_read_at_all(fh, 0, buf, 1, newtype, &status);
    if (errcode != MPI_SUCCESS) {
	    handle_error(errcode, "nc mem - nc file: MPI_File_read_at_all");
    }

    /* the verification for N compute nodes is tricky. Say we have 3
     * processors.  
     * process 0 sees: 0 -1 -1 3 -1 -1 ...
     * process 1 sees: -1 34 -1 -1 37 -1 ...
     * process 2 sees: -1 -1 68 -1 -1 71 ... */

    /* verify those leading -1s exist if they should */
    for (i=0; i<mynod; i++ ) {
	    if ( buf[i] != -1 ) {
		    if(verbose) fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]);
		    errors++;
	    }
    }
    /* now the modulo games are hairy.  processor 0 sees real data in the 0th,
     * 3rd, 6th... elements of the buffer (assuming nprocs==3 ).  proc 1 sees
     * the data in 1st, 4th, 7th..., and proc 2 sees it in 2nd, 5th, 8th */

    for(/* 'i' set in above loop */; i<SIZE; i++) {
	    if ( ((i-mynod)%nprocs) && buf[i] != -1)  {
		    if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", 
				    mynod, i, buf[i]);
		    errors++;
	    }
	    if ( !((i-mynod)%nprocs) && buf[i] != SEEDER(mynod,i,SIZE) ) {
		    if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
				    mynod, i, buf[i], SEEDER(mynod,i,SIZE));
		    errors++;
	    }
    }
    MPI_File_close(&fh);

    MPI_Barrier(MPI_COMM_WORLD);

    if (!mynod) {
	if(verbose) fprintf(stderr, "\ntesting noncontiguous in memory, contiguous in file using collective I/O\n");
	MPI_File_delete(filename, info);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
                  info, &fh);

    for (i=0; i<SIZE; i++) buf[i] = SEEDER(mynod,i,SIZE);
    errcode = MPI_File_write_at_all(fh, mynod*(SIZE/nprocs)*sizeof(int), 
		    buf, 1, newtype, &status);
    if (errcode != MPI_SUCCESS)
	    handle_error(errcode, "nc mem - c file: MPI_File_write_at_all");

    MPI_Barrier(MPI_COMM_WORLD);

    for (i=0; i<SIZE; i++) buf[i] = -1;

    errcode = MPI_File_read_at_all(fh, mynod*(SIZE/nprocs)*sizeof(int), 
		    buf, 1, newtype, &status);
    if (errcode != MPI_SUCCESS)
	    handle_error(errcode, "nc mem - c file: MPI_File_read_at_all");

    /* just like as above */
    for (i=0; i<mynod; i++ ) {
	    if ( buf[i] != -1 ) {
		    if(verbose) fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]);
		    errors++;
	    }
    }
    for(/* i set in above loop */; i<SIZE; i++) {
	    if ( ((i-mynod)%nprocs) && buf[i] != -1)  {
		    if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", 
				    mynod, i, buf[i]);
		    errors++;
	    }
	    if ( !((i-mynod)%nprocs) && buf[i] != SEEDER(mynod,i,SIZE)) {
		    if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
				    mynod, i, buf[i], SEEDER(mynod,i,SIZE) );
		    errors++;
	    }
    }

    MPI_File_close(&fh);

    MPI_Barrier(MPI_COMM_WORLD);

    if (!mynod) {
	if(verbose) fprintf(stderr, "\ntesting contiguous in memory, noncontiguous in file using collective I/O\n");
	MPI_File_delete(filename, info);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
                  info, &fh);

    MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);

    for (i=0; i<SIZE; i++) buf[i] = SEEDER(mynod, i, SIZE);
    errcode = MPI_File_write_all(fh, buf, SIZE, MPI_INT, &status);
    if (errcode != MPI_SUCCESS)
	    handle_error(errcode, "c mem - nc file: MPI_File_write_all");

    MPI_Barrier(MPI_COMM_WORLD);

    for (i=0; i<SIZE; i++) buf[i] = -1;

    errcode = MPI_File_read_at_all(fh, 0, buf, SIZE, MPI_INT, &status);
    if (errcode != MPI_SUCCESS)
	    handle_error(errcode, "c mem - nc file: MPI_File_read_at_all");

    /* same crazy checking */
    for (i=0; i<SIZE; i++) {
	    if (buf[i] != SEEDER(mynod, i, SIZE)) {
		if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], SEEDER(mynod, i, SIZE));
		errors++;
	    }
    }

    MPI_File_close(&fh);

    MPI_Type_free(&newtype);
    free(buf);
    if (info != MPI_INFO_NULL) MPI_Info_free(&info);
    return errors;
}
/* *************************** *
 *  Main computational kernel  *
 * *************************** */
int correlationKernel(int rank,
                      int size,
                      double* dataMatrixX,
                      double* dataMatrixY,
                      int columns,
                      int rows,
                      char *out_filename,
                      int distance_flag) {

    int local_check = 0, global_check = 0;
    int i = 0, j, taskNo;
    int err, count = 0;
    unsigned long long fair_chunk = 0, coeff_count = 0;
    unsigned int init_and_cleanup_loop_iter=0;
    unsigned long long cor_cur_size = 0;
    
    double start_time, end_time;

    // Variables needed by the Indexed Datatype
    MPI_Datatype coeff_index_dt;
    MPI_File fh;
    int *blocklens, *indices;

    MPI_Status stat;
    MPI_Comm comm = MPI_COMM_WORLD;

    // Master processor keeps track of tasks
    if (rank == 0) {

        // Make sure everything will work fine even if there are
        // less genes than available workers (there are size-1 workers
        // master does not count)
        if ( (size-1) > rows )
            init_and_cleanup_loop_iter = rows+1;
        else
            init_and_cleanup_loop_iter = size;

        // Start timer
        start_time = MPI_Wtime();

        // Send out initial tasks (remember you have size-1 workers, master does not count)
        for (i=1; i<init_and_cleanup_loop_iter; i++) {
            taskNo = i-1;
            err = MPI_Send(&taskNo, 1, MPI_INT, i, 0, comm);
        }        

        // Terminate any processes that were not working due to the fact
        // that the number of rows where less than the actual available workers
        for(i=init_and_cleanup_loop_iter; i < size; i++) {
            PROF(rank, "\nPROF_idle : Worker %d terminated due to insufficient work load", i);
            err = -1;
            err = MPI_Send(&err, 1, MPI_INT, i, 0, comm);
        }

        // Wait for workers to finish their work assignment and ask for more
        for (i=init_and_cleanup_loop_iter-1; i<rows; i++) {
            err = MPI_Recv(&taskNo, 1, MPI_INT, MPI_ANY_SOURCE, 0, comm, &stat);

            // Check taskNo to make sure everything is ok. Negative means there is problem
            // thus terminate gracefully all remaining working workers
            if ( taskNo < 0 ) {
                // Reduce by one because one worker is already terminated
                init_and_cleanup_loop_iter--;
                // Break and cleanup
                break;
            }

            // The sending processor is ready to work:
            // It's ID is in stat.MPI_SOURCE
            // Send it the current task (i)
            err = MPI_Send(&i, 1, MPI_INT, stat.MPI_SOURCE, 0, comm);
        }

        // Clean up processors
        for (i=1; i<init_and_cleanup_loop_iter; i++) {
            // All tasks complete - shutdown workers
            err = MPI_Recv(&taskNo, 1, MPI_INT, MPI_ANY_SOURCE, 0, comm, &stat);
            // If process failed then it will not be waiting to receive anything
            // We have to ignore the send because it will deadlock
            if ( taskNo < 0 )
                continue;
            err = -1;
            err = MPI_Send(&err, 1, MPI_INT, stat.MPI_SOURCE, 0, comm);
        }

        // Master is *always* OK
        local_check = 0;
        MPI_Allreduce(&local_check, &global_check, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

        // Check failed, abort
        if ( global_check != 0 ) {
            return -1;
        }
        
        // Stop timer
        end_time = MPI_Wtime();
        PROF(rank, "\nPROF_comp (workers=%d) : Time taken by correlation coefficients computations : %g\n", size-1, end_time - start_time);

        // Start timer
        start_time = MPI_Wtime();

        // Master process must call MPI_File_set_view as well, it's a collective call
        // Open the file handler
        MPI_File_open(comm, out_filename, MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);

        // Create the file view
        MPI_File_set_view(fh, 0, MPI_DOUBLE, MPI_DOUBLE, "native", MPI_INFO_NULL);

        // Write data to disk
        MPI_File_write_all(fh, &cor[0], 0, MPI_DOUBLE, &stat);

        // Stop timer
        end_time = MPI_Wtime();
        PROF(rank, "\nPROF_write (workers=%d) : Time taken for global write-file : %g\n",  size-1, end_time - start_time);

    } else {

        // Compute how many workers will share the work load
        // Two scenarios exist:
        // (1) more OR equal number of workers and rows exist
        // (2) more rows than workers
        if ( (size-1) > rows ) {
            // For this scenario each worker will get exaclty one work asssignment.
            // There is not going to be any other work so it only compute "rows" number
            // of coefficients
            fair_chunk = rows;
            cor_cur_size = fair_chunk;
        } else {
            // For this scenario we are going to allocate space equal to a fair
            // distribution of work assignments *plus* an extra amount of space to
            // cover any load imbalancing. This amount is expressed as a percentage
            // of the fair work distribution (see on top, 20% for now)

            // Plus 1 to round it up or just add some extra space, both are fine
            fair_chunk = (rows / (size-1)) + 1;
            DEBUG("fair_chunk %d \n", fair_chunk);

            // We can use "j" as temporary variable.
            // Plus 1 to avoid getting 0 from the multiplication.
            j = (fair_chunk * MEM_PERC) + 1;

            cor_cur_size = (fair_chunk + j) * rows;
            DEBUG("cor_cur_size %lld \n", cor_cur_size);
        }

        // Allocate memory
        DEBUG("cor_cur_size %lld \n", cor_cur_size);
        long long double_size = sizeof(double);
        DEBUG("malloc size %lld \n", (double_size * cor_cur_size));
        cor = (double *)malloc(double_size * cor_cur_size);

        blocklens = (int *)malloc(sizeof(int) * rows);
        indices = (int *)malloc(sizeof(int) * rows);

        mean_value_vectorX = (double *)malloc(sizeof(double) * rows);
        Sxx_vector = (double *)malloc(sizeof(double) * rows);
        mean_value_vectorY = (double *)malloc(sizeof(double) * rows);
        Syy_vector = (double *)malloc(sizeof(double) * rows);

        // Check that all memory is successfully allocated
        if ( ( cor == NULL ) || ( blocklens == NULL ) || ( indices == NULL ) || 
             ( mean_value_vectorX == NULL ) || ( Sxx_vector == NULL ) ||
             ( mean_value_vectorY == NULL ) || ( Syy_vector == NULL ) ) {
            ERR("**ERROR** : Memory allocation failed on worker process %d. Aborting.\n", rank);

            // Free allocated memory
            free_all(cor, blocklens, indices, mean_value_vectorX, Sxx_vector, mean_value_vectorY, Syy_vector);

            // Let the master process know its aborting in order to terminate
            // the rest of the working workers
            // We have to receive a work assignment first and then terminate
            // otherwise the master will deadlock trying to give work to this worker
            err = MPI_Recv(&taskNo, 1, MPI_INT, 0, 0, comm, &stat);
            taskNo = -1;
            err = MPI_Send(&taskNo, 1, MPI_INT, 0, 0, comm);

            // This worker failed
            local_check = 1;
            MPI_Allreduce(&local_check, &global_check, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

            return -1;
        }

        // Compute necessary parameters for Pearson method
        // (this will transform the values of the input array to more meaningful data
        //  and save us from a lot of redundant computations)
        compute_parameters(dataMatrixX, dataMatrixY, rows, columns);

        // Main loop for workers. They get work from master, compute coefficients,
        // save them to their *local* vector and ask for more work
        for(;;) {
            // Get work
            err = 0;
            err = MPI_Recv(&taskNo, 1, MPI_INT, 0, 0, comm, &stat);

            // If received task is -1, function is terminated
            if ( taskNo == -1 )  break;

            // Check if there is enough memory to store the new coefficients, if not reallocate
            // the current memory and expand it by MEM_PERC of the approximated size
            if ( cor_cur_size < (coeff_count + rows) ) {
                PROF(0, "\n**WARNING** : Worker process %3d run out of memory and reallocates. Potential work imbalancing\n", rank);
                DEBUG("\n**WARNING** : Worker process %3d run out of memory and reallocates. Potential work imbalancing\n", rank);

                // Use j as temporary again. Add two (or any other value) to avoid 0.
                // (two is just a random value, you can put any value really...)
                j = (fair_chunk * MEM_PERC) + 2;
                cor_cur_size += (j * rows);

                // Reallocate and check
                cor = (double *)realloc(cor, sizeof(double) * cor_cur_size);
                if ( cor == NULL ) {
                    ERR("**ERROR** : Memory re-allocation failed on worker process %d. Aborting.\n", rank);

                    // Let the master process know its aborting in order to terminate
                    // the rest of the working workers
                    taskNo = -1;
                    err = MPI_Send(&taskNo, 1, MPI_INT, 0, 0, comm);

                    // This worker failed
                    local_check = 1;
                    MPI_Allreduce(&local_check, &global_check, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

                    // Free all allocated memory
                    free_all(cor, blocklens, indices, mean_value_vectorX, Sxx_vector, mean_value_vectorY, Syy_vector);

                    return -1;
                }
            }

            // Compute the correlation coefficients
            if(dataMatrixY != NULL) {
              for (j=0; j < rows; j++) {
                cor[coeff_count] = pearson_XY(dataMatrixX, dataMatrixY, j, taskNo, columns);
                coeff_count++;
              }

            } else {
              for (j=0; j < rows; j++) {
                // Set main diagonal to 1
                if ( j == taskNo ) {
                  cor[coeff_count] = 1.0;
                  coeff_count++;
                  continue;
                }
                cor[coeff_count] = pearson(dataMatrixX, taskNo, j, columns);
                coeff_count++;
              }
            }

            // The value of blocklens[] represents the number of coefficients on each
            // row of the corellation array
            blocklens[count] = rows;

            // The value of indices[] represents the offset of each row in the data file
            indices[count] = (taskNo * rows);
            count++;

            // Give the master the taskID
            err = MPI_Send(&taskNo, 1, MPI_INT, 0, 0, comm);
        }

        // There are two possibilities
        //   (a) everything went well and all workers finished ok
        //   (b) some processes finished ok but one or more of the remaining working workers failed
        // To make sure all is well an all-reduce will be performed to sync all workers and guarantee success
        // before moving on to write the output file
        // This worker is OK
        local_check = 0;
        MPI_Allreduce(&local_check, &global_check, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

        // Check failed
        if ( global_check != 0 ) {
            // Free all allocated memory
          free_all(cor, blocklens, indices, mean_value_vectorX, Sxx_vector, mean_value_vectorY, Syy_vector);
            return -1;
        }

        PROF(0, "\nPROF_stats (thread %3d) : Fair chunk of work : %d \t\t Allocated : %d \t\t Computed : %d\n",
                rank, fair_chunk, cor_cur_size, coeff_count);

        // If the distance_flag is set, then transform all correlation coefficients to distances
        if ( distance_flag == 1 ) {
            for(j=0; j < coeff_count; j++) {
                cor[j] = 1 - cor[j];
            }
        }

        // Create and commit the Indexed datatype *ONLY* if there are data available
        if ( coeff_count != 0 ) {
            MPI_Type_indexed(count, blocklens, indices, MPI_DOUBLE, &coeff_index_dt);
            MPI_Type_commit(&coeff_index_dt);
        }

        // Open the file handler
        MPI_File_open(comm, out_filename, MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);

        // Create the file view
        if ( coeff_count != 0 ) {
            MPI_File_set_view(fh, 0, MPI_DOUBLE, coeff_index_dt, "native", MPI_INFO_NULL);
        } else {
            MPI_File_set_view(fh, 0, MPI_DOUBLE, MPI_DOUBLE, "native", MPI_INFO_NULL);
        }

        // Write data to disk
        // TODO coeff_count cannot be greater than max int (for use in the MPI_File_write_all call). 
        // A better fix should be possible, for now throw error.
        
        DEBUG("\ncoeff_count is %lld\n", coeff_count);
        DEBUG("\INT_MAX is %d\n", INT_MAX);
        if(coeff_count>INT_MAX)
        {
            ERR("**ERROR** : Could not run as the chunks of data are too large. Try running again with more MPI processes.\n");

            // Free allocated memory
            free_all(cor, blocklens, indices, mean_value_vectorX, Sxx_vector, mean_value_vectorY, Syy_vector);

            // Let the master process know its aborting in order to terminate
            // the rest of the working workers
            // We have to receive a work assignment first and then terminate
            // otherwise the master will deadlock trying to give work to this worker
            err = MPI_Recv(&taskNo, 1, MPI_INT, 0, 0, comm, &stat);
            taskNo = -1;
            err = MPI_Send(&taskNo, 1, MPI_INT, 0, 0, comm);

            // This worker failed
            local_check = 1;
            MPI_Allreduce(&local_check, &global_check, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

            return -1;
        }

        
        
        DEBUG("\nWriting %d to disk\n", coeff_count);

        MPI_File_write_all(fh, &cor[0], coeff_count, MPI_DOUBLE, &stat);

        if (coeff_count != 0 )
            MPI_Type_free(&coeff_index_dt);

        // Free all allocated memory
        free_all(cor, blocklens, indices, mean_value_vectorX, Sxx_vector, mean_value_vectorY, Syy_vector);
    }

         DEBUG("\nAbout to write to disk %d\n", rank);
    MPI_File_sync( fh ) ;   		// Causes all previous writes to be transferred to the storage device
         DEBUG("\nWritten to disk %d\n",rank);
  //  MPI_Barrier( MPI_COMM_WORLD ) ; 	// Blocks until all processes in the communicator have reached this routine.
         DEBUG("\nAfter barrier \n", rank);

    // Close file handler
    MPI_File_close(&fh);
  DEBUG("\nAfter file closed /n");
   // MPI_Barrier( MPI_COMM_WORLD ) ; 	// Blocks until all processes in the communicator have reached this routine.
      DEBUG("\nAbout to return from kernel /n");
      return 0;
}
Exemple #9
0
void parallel_readwrite(char *file_name, void *dump_buffer,
                            int type_of_file, int is_write, long long offset)
{
#if MPI && DO_PARALLEL_WRITE
  MPI_File fh;
  MPI_Status status;
  MPI_Datatype mpi_elementary_type, mpi_file_type;
  int file_open_error, file_write_error ;
  int error_string_length;
  char error_string[BUFSIZ];
  MPI_Offset file_size;
  int count;
  void *mpi_buffer;
  size_t mpi_buffer_size;
  int mode;
  MPI_Offset mpi_offset;
    
  MPI_Barrier(MPI_COMM_WORLD);
  
  if (is_write) {
    mode = MPI_MODE_CREATE | MPI_MODE_WRONLY | MPI_MODE_APPEND;
  }
  else {
    mode = MPI_MODE_RDONLY;
  }
  file_open_error = MPI_File_open(MPI_COMM_WORLD, file_name,
                                  mode,
                                  MPI_INFO_NULL, &fh);
  if (file_open_error != MPI_SUCCESS) {
    MPI_Error_string(file_open_error, error_string,
                     &error_string_length);
    fprintf(stderr, "parallel_readwrite(): error opening file: %3d: %s\n", mpi_rank, error_string);
    MPI_Abort(MPI_COMM_WORLD, file_open_error);
    
    /* It is still OK to abort, because we have failed to
     open the file. */
    
  }
  else {
    
//    if (i_am_the_master)
//      chmod(file_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    if (offset < 0L) {
      if(is_write) {
        MPI_File_get_position(fh, &mpi_offset);
        offset = mpi_offset;
      }
      else {
        offset = 0L;
      }
    }
    MPI_Barrier(MPI_COMM_WORLD);
    //differentiate data type and buffers involved based on file type
    if( DUMP_FILE == type_of_file ) {
        mpi_elementary_type = MPI_DUMP_TYPE;
        mpi_file_type = dump_file_type;
        mpi_buffer = (void*)dump_buffer;
        mpi_buffer_size = dump_buffer_size;
    }
    else if( GDUMP_FILE == type_of_file){
        mpi_elementary_type = MPI_GDUMP_TYPE;
        mpi_file_type = gdump_file_type;
        mpi_buffer = (void*)gdump_buffer;
        mpi_buffer_size = gdump_buffer_size;
    }
    else if( GDUMP2_FILE == type_of_file){
      mpi_elementary_type = MPI_GDUMP2_TYPE;
      mpi_file_type = gdump2_file_type;
      mpi_buffer = (void*)gdump2_buffer;
      mpi_buffer_size = gdump2_buffer_size;
    }
    else if( RDUMP_FILE == type_of_file){
        mpi_elementary_type = MPI_RDUMP_TYPE;
        mpi_file_type = rdump_file_type;
        mpi_buffer = (void*)rdump_buffer;
        mpi_buffer_size = rdump_buffer_size;
    }
    else if( FDUMP_FILE == type_of_file){
      mpi_elementary_type = MPI_FDUMP_TYPE;
      mpi_file_type = fdump_file_type;
      mpi_buffer = (void*)fdump_buffer;
      mpi_buffer_size = fdump_buffer_size;
    }
    else {
        if(i_am_the_master)
            fprintf(stderr, "Unknown file type %d\n", type_of_file);
        MPI_File_close(&fh);
        MPI_Finalize();
        exit(2);
    }
    MPI_File_set_view(fh, offset, mpi_elementary_type, mpi_file_type, "native", MPI_INFO_NULL);
    if (is_write) {
      file_write_error =
      MPI_File_write_all(fh, mpi_buffer, mpi_buffer_size, mpi_elementary_type,
                         &status);
    }
    else {
      file_write_error =
      MPI_File_read_all(fh, mpi_buffer, mpi_buffer_size, mpi_elementary_type,
                         &status);
    }
    if (file_write_error != MPI_SUCCESS) {
      MPI_Error_string(file_write_error, error_string,
                       &error_string_length);
      fprintf(stderr, "parallel_readwrite(): error %s file: %3d: %s\n",
              (is_write)?("writing"):("reading"), mpi_rank, error_string);
      MPI_File_close(&fh);
      //if (i_am_the_master) MPI_File_delete(file_name, MPI_INFO_NULL);
      MPI_Finalize();
      exit(1);
    }
//    MPI_Get_count(&status, MPI_FLOAT, &count);
//    MPI_File_get_size(fh, &file_size);
//    if(1) {
//      printf("%3d: wrote %d floats, expected to write %lld floats\n", mpi_rank, count, (long long int)dump_buffer_size);
//      printf("%3d: file size is %lld bytes, header-related offset is %lld\n", mpi_rank, file_size, offset);
//    }

    MPI_File_close(&fh);
  }
#endif
}
Exemple #10
0
int main(int argc, char *argv[])
{
    char *filename;
    int i, len, nprocs, amode, err, nerrs = 0;
    int blen[2], disp[2];
    MPI_Datatype etype, filetype;
    MPI_File fh;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

    if (nprocs != 1) {
        fprintf(stderr, "Run this program on 1 process\n");
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

    i = 1;
    while ((i < argc) && strcmp("-fname", *argv)) {
        i++;
        argv++;
    }
    if (i >= argc) {
        len = 8;
        filename = (char *) malloc(len + 10);
        strcpy(filename, "testfile");
    } else {
        argv++;
        len = (int) strlen(*argv);
        filename = (char *) malloc(len + 1);
        strcpy(filename, *argv);
    }

    MPI_File_delete(filename, MPI_INFO_NULL);

    amode = MPI_MODE_RDWR | MPI_MODE_CREATE;
    err = MPI_File_open(MPI_COMM_WORLD, filename, amode, MPI_INFO_NULL, &fh);
    CHECK_ERROR(err, nerrs);

    /* create etype with negative disp */
    disp[0] = -2;
    disp[1] = 2;
    blen[0] = 1;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, etype, etype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);
    err = MPI_Type_free(&etype);
    CHECK_ERROR(err, nerrs);

    /* create etype with decreasing disp */
    disp[0] = 3;
    blen[0] = 1;
    disp[1] = 0;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, etype, etype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);

    err = MPI_Type_free(&etype);
    CHECK_ERROR(err, nerrs);

    /* create etype with overlaps */
    disp[0] = 0;
    blen[0] = 3;
    disp[1] = 1;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, etype, etype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);

    err = MPI_Type_free(&etype);
    CHECK_ERROR(err, nerrs);

    /* create filetype with negative disp */
    disp[0] = -2;
    disp[1] = 2;
    blen[0] = 1;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, MPI_INT, filetype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);

    err = MPI_Type_free(&filetype);
    CHECK_ERROR(err, nerrs);

    /* create filetype with decreasing disp */
    disp[0] = 3;
    blen[0] = 1;
    disp[1] = 0;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, MPI_INT, filetype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);

    err = MPI_Type_free(&filetype);
    CHECK_ERROR(err, nerrs);

    /* create filetype with overlaps */
    disp[0] = 0;
    blen[0] = 3;
    disp[1] = 1;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, MPI_INT, filetype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);

    err = MPI_Type_free(&filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_close(&fh);
    CHECK_ERROR(err, nerrs);

    /* open the file for read only */
    amode = MPI_MODE_RDONLY;
    err = MPI_File_open(MPI_COMM_WORLD, filename, amode, MPI_INFO_NULL, &fh);
    CHECK_ERROR(err, nerrs);

    /* create etype with negative disp */
    disp[0] = -2;
    disp[1] = 2;
    blen[0] = 1;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, etype, etype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);

    err = MPI_Type_free(&etype);
    CHECK_ERROR(err, nerrs);

    /* create etype with decreasing disp */
    disp[0] = 3;
    blen[0] = 1;
    disp[1] = 0;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, etype, etype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);

    err = MPI_Type_free(&etype);
    CHECK_ERROR(err, nerrs);

    /* create etype with overlaps (should be OK for read-only) */
    disp[0] = 0;
    blen[0] = 3;
    disp[1] = 1;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&etype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, etype, etype, "native", MPI_INFO_NULL);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_free(&etype);
    CHECK_ERROR(err, nerrs);

    /* create filetype with negative disp */
    disp[0] = -2;
    disp[1] = 2;
    blen[0] = 1;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, MPI_INT, filetype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);

    err = MPI_Type_free(&filetype);
    CHECK_ERROR(err, nerrs);

    /* create filetype with decreasing disp */
    disp[0] = 3;
    blen[0] = 1;
    disp[1] = 0;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, MPI_INT, filetype, "native", MPI_INFO_NULL);
    CHECK_EXPECTED_ERROR(MPI_ERR_IO, err, nerrs);

    err = MPI_Type_free(&filetype);
    CHECK_ERROR(err, nerrs);

    /* create filetype with overlaps (should be OK for read-only) */
    disp[0] = 0;
    blen[0] = 3;
    disp[1] = 1;
    blen[1] = 1;
    err = MPI_Type_indexed(2, blen, disp, MPI_INT, &filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_commit(&filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_set_view(fh, 0, MPI_INT, filetype, "native", MPI_INFO_NULL);
    CHECK_ERROR(err, nerrs);

    err = MPI_Type_free(&filetype);
    CHECK_ERROR(err, nerrs);

    err = MPI_File_close(&fh);
    CHECK_ERROR(err, nerrs);

    if (nerrs == 0)
        printf(" No Errors\n");
    MPI_Finalize();

    return (nerrs > 0);
}
int main(int argc, char *argv[] ) {
	double time1, time2;
	
	time1 = MPI_Wtime();

	int rank, processors;
	
	int j;	// number of iterations
	int k;	// number of iterations to perform before creating a checkpoint
	int l;  // number of random samples per grid point
	int checkpoint_resume = 0;	// 1 = resume from last checkpoint

	int c;		// used to hold a character
	int i=0, row = 0, col = 0, pln = 0;	// array iterators

	char ***local_array;		   
	char **local_array_2nd;		   
	char *local_array_pointer; 

	char ***local_array_copy;		   
	char **local_array_copy_2nd;		   
	char *local_array_copy_pointer; 

	char ***temp, *temp_pointer;
	
	int file_open_error;
	int command_line_incomplete = 0;

	int grid_size[3] 	  = {0,0,0};
	int proc_size[3] 	  = {0,0,0};
	int local_size[3] 	  = {0,0,0};
	int remainder_size[3] = {0,0,0};
	int coords[3] 		  = {0,0,0};
	int start_indices[3]  = {0,0,0};
	int periods[3]        = {0,0,0};
	int mem_size[3]       = {0,0,0};
	
	MPI_Status status;
	MPI_Datatype filetype, memtype;
	MPI_File fh;
	
	MPI_Init(&argc, &argv);
	MPI_Comm_size(MPI_COMM_WORLD, &processors);	
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);	

	// Interpret the command line arguments --------------------------------
  	if (rank == 0) {  	  	
		
		if (argc < 6 || argc > 8) {
			fputs("usage: x y z j k l r\n", stderr);
			fputs("where: x,y,z = x, y and z dimensions\n", stderr);
			fputs("       j = how many times the game of life is played\n", stderr);
			fputs("       k = checkpoint every k iterations\n", stderr);
			fputs("       l = number of random samples per grid point\n", stderr);
			fputs("       r = resume from the last checkpoint\n", stderr);
			fputs(INITIAL, stderr);
			fputs(" must be present.\n", stderr);
			fputs(CHECKPOINT, stderr);
			fputs(" must be present if resuming from the last checkpoint.\n", stderr);
			exit(EXIT_FAILURE);
		}

  	}

	j = (int) strtol(argv[4], NULL, 10);
	k = (int) strtol(argv[5], NULL, 10);
	l = (int) strtol(argv[6], NULL, 10);		
	if ( argc == 7 )
		if ( argv[6][0] == 'r' )
			checkpoint_resume = 1;			

	if (rank == 0)
		printf("%d iterations \ncheckpoint every %d iterations \n%d samples per grid point \ncheckpoint resume = %d\n", j,k,l,checkpoint_resume);				
	
	grid_size[0] = (int) strtol(argv[1], NULL, 10);
	grid_size[1] = (int) strtol(argv[2], NULL, 10);
	grid_size[2] = (int) strtol(argv[3], NULL, 10);
	if (rank==0) printf("grid_size: %d, %d, %d\n", grid_size[0], grid_size[1], grid_size[2]);

	MPI_Dims_create(processors, 3, proc_size);
	if (rank==0) printf("proc_size: %d, %d, %d\n", proc_size[0], proc_size[1], proc_size[2]);

	local_size[0] = grid_size[0] / proc_size[0];
	local_size[1] = grid_size[1] / proc_size[1];
	local_size[2] = grid_size[2] / proc_size[2];
	if (rank==0) printf("local_size: %d, %d, %d\n", local_size[0], local_size[1], local_size[2]);

	remainder_size[0] = grid_size[0] % proc_size[0];
	remainder_size[1] = grid_size[1] % proc_size[1];
	remainder_size[2] = grid_size[2] % proc_size[2];
	if (rank==0) printf("remainder_size: %d, %d, %d\n", remainder_size[0], remainder_size[1], remainder_size[2]);
	if (remainder_size[0] != 0 || remainder_size[1] != 0 || remainder_size[2] != 0) {
		fputs("remainder size != 0, check your dimensions", stderr);
		MPI_Finalize();
		exit(EXIT_FAILURE);
	}

	MPI_Comm comm;
	MPI_Cart_create(MPI_COMM_WORLD, 3, proc_size, periods, 0, &comm);
	MPI_Comm_rank(comm, &rank);
	MPI_Cart_coords(comm, rank, 3, coords);

	start_indices[0] = coords[0] * local_size[0];
	start_indices[1] = coords[1] * local_size[1];
	start_indices[2] = coords[2] * local_size[2];

/*	printf("A coords R%d: (%d, %d, %d)  (%d, %d, %d)\n", rank, coords[0], coords[1], coords[2], start_indices[0], start_indices[1], start_indices[2]);*/
	fflush(stdout);
	
	// create the file type ---------------------------------------------------
	MPI_Type_create_subarray(3, grid_size, local_size, start_indices, MPI_ORDER_C, MPI_CHAR, &filetype); 
	MPI_Type_commit(&filetype);
	
	// create a local memory type with ghost rows -----------------------------
	mem_size[0] = local_size[0] + 2; 
	mem_size[1] = local_size[1] + 2; 
	mem_size[2] = local_size[2] + 2; 
	start_indices[0] = start_indices[1] = start_indices[2] = 1;
	
	MPI_Type_create_subarray(3, mem_size, local_size, start_indices, MPI_ORDER_C, MPI_CHAR, &memtype);
	MPI_Type_commit(&memtype);
	
	// find my neighbors ------------------------------------------------------

	int nxminus, nxplus, nyminus, nyplus, nzminus, nzplus, tag = 333, *neighbors;

	// Neighbors Array:  row-  col-  col+  row+  plane-  plane+

	neighbors = (int *) malloc(6 * sizeof(int));
	for(i=0; i<6; i++)
		neighbors[i] = rank;

	MPI_Cart_shift(comm, 0, 1, &nxminus, &nxplus);
	MPI_Cart_shift(comm, 1, 1, &nyminus, &nyplus);
	MPI_Cart_shift(comm, 2, 1, &nzminus, &nzplus);

//	printf(" %d sending south to %d receiving from %d \n",rank,nxplus,nxminus);
//	fflush(stdout);
	MPI_Sendrecv(&rank, 1, MPI_INT, nxplus, tag, 
		&(neighbors[0]), 1, MPI_INT, nxminus, tag, comm, &status);

//	printf(" %d sending North to %d receiving from %d \n",rank,nxminus,nxplus);
//	fflush(stdout);
	MPI_Sendrecv(&rank, 1, MPI_INT, nxminus, tag, 
		&(neighbors[3]), 1, MPI_INT, nxplus, tag, comm, &status);

//	printf(" %d sending East to %d receiving from %d \n",rank,nyplus,nyminus);
//	fflush(stdout);
	MPI_Sendrecv(&rank, 1, MPI_INT, nyplus, tag, 
		&neighbors[1], 1, MPI_INT, nyminus, tag, comm, &status);

//	printf(" %d sending West to %d receiving from %d \n",rank,nyminus,nyplus);
//	fflush(stdout);
	MPI_Sendrecv(&rank, 1, MPI_INT, nyminus, tag, 
		&neighbors[2], 1, MPI_INT, nyplus, tag, comm, &status);

//	printf(" %d sending backwards to %d receiving from %d \n",rank,nzplus,nzminus);
//	fflush(stdout);
	MPI_Sendrecv(&rank, 1, MPI_INT, nzplus, tag, 
		&(neighbors[4]), 1, MPI_INT, nzminus, tag, comm, &status);

//	printf(" %d sending forward to %d receiving from %d \n",rank,nzminus,nzplus);
//	fflush(stdout);
	MPI_Sendrecv(&rank, 1, MPI_INT, nzminus, tag, 
		&(neighbors[5]), 1, MPI_INT, nzplus, tag, comm, &status);

/*	printf("neighboors R%d : (row-) %d (col-) %d (col+) %d (row+) %d (plane-) %d (plane+) %d\n",rank,neighbors[0],neighbors[1],neighbors[2],neighbors[3],neighbors[4],neighbors[5]);*/
	fflush(stdout);	

	//init_sprng(1,time(0),SPRNG_DEFAULT);
	srand((unsigned int)time(NULL));
		
	// Open the initial condition (checkpoint or not) ----------------------

	if ( checkpoint_resume ) {
		file_open_error = 
		MPI_File_open(MPI_COMM_WORLD, CHECKPOINT, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
		MPI_File_set_view(fh,0, MPI_CHAR, filetype, "native", MPI_INFO_NULL);
	}
	else {
		file_open_error = 
		MPI_File_open(MPI_COMM_WORLD, INITIAL, MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
		MPI_File_set_view(fh,0, MPI_CHAR, filetype, "native", MPI_INFO_NULL);
	}
	if (file_open_error != MPI_SUCCESS) {
		if (checkpoint_resume)
			fputs(CHECKPOINT, stderr);
		else
			fputs(INITIAL, stderr);
		fputs(" could not be opened.\n", stderr);
		exit(EXIT_FAILURE);
	}

	// Allocate and Populate the local array ----------------------------------
	
	local_array_copy_pointer = (char *)   malloc(mem_size[0] * mem_size[1] * mem_size[2] * sizeof(char));
	local_array_copy_2nd     = (char **)  malloc(mem_size[0] * mem_size[1] * sizeof(char*));
	local_array_copy         = (char ***) malloc(mem_size[0] * sizeof(char*));
	for(i = 0; i < mem_size[0] * mem_size[1]; i++)
		local_array_copy_2nd[i] = &local_array_copy_pointer[i * mem_size[2]];
	for(i = 0; i < mem_size[0]; i++)
		local_array_copy[i] = &local_array_copy_2nd[i * mem_size[1]];

	local_array_pointer = (char *)   malloc(mem_size[0] * mem_size[1] * mem_size[2] * sizeof(char));
	local_array_2nd  	= (char **)  malloc(mem_size[0] * mem_size[1] * sizeof(char*));
	local_array			= (char ***) malloc(mem_size[0] * sizeof(char*));
	for(i = 0; i < mem_size[0] * mem_size[1]; i++)
		local_array_2nd[i] = &local_array_pointer[i * mem_size[2]];
	for(i = 0; i < mem_size[0]; i++)
		local_array[i] = &local_array_2nd[i * mem_size[1]];
	
	// if (rank==0) printf("Malloc complete\n");
	
	for(row=0; row<mem_size[0]; row++) {
		for(col=0; col<mem_size[1]; col++) {
			for(pln=0; pln<mem_size[2]; pln++) {
				local_array[row][col][pln] = local_array_copy[row][col][pln] = '0';
			}
		}
	}
	
	// if (rank==0) printf("Setup complete\n");

	MPI_File_read_all(fh, local_array_pointer, 1, memtype, &status);

	if (rank==0) printf("File Read\n");
	
//	if (rank==0) {
//	for(row=0; row<mem_size[0]; row++) {
//		for(col=0; col<mem_size[1]; col++) {
//			for(pln=0; pln<mem_size[2]; pln++) {
//				printf("%c", local_array[row][col][pln]);
//			}
//			printf("\n");
//		}
//		printf("-----------------------\n");
//	}
//	}
	
	MPI_File_close(&fh);
		
	// Construct the plane data types
	
	MPI_Datatype yzplane;
	MPI_Type_vector(local_size[1], local_size[2], local_size[2]+2, MPI_CHAR, &yzplane);
	MPI_Type_commit(&yzplane);

	MPI_Datatype xzplane;
	MPI_Type_vector(local_size[0], local_size[2], ((local_size[2]+2)*local_size[1])+((local_size[2]+2)*2), MPI_CHAR, &xzplane);
	MPI_Type_commit(&xzplane);

	// this type will also copy the corner x columns, can't skip blocks intermittently
	// since we aren't worrying about the corner data, it's ok
	MPI_Datatype xyplane; 
	MPI_Type_vector((local_size[0]*local_size[1])+((local_size[0]*2)-2), 1, local_size[2]+2, MPI_CHAR, &xyplane);
	MPI_Type_commit(&xyplane);
					
	MPI_Barrier(comm);
	
	// start the iteration loop
	
	int iterations;
	int kCounter = k;
	for (iterations = 0; iterations < j; iterations++) {

		// send updated planes
		// Neighbors Array:  
		// 0     1     2     3     4       5
		// row-  col-  col+  row+  plane-  plane+
		// Note: corners are not handled
		
		// send top yzplane
		if (rank != neighbors[0]) MPI_Send(&local_array[1][1][1], 1, yzplane, neighbors[0], 0, comm);
		// recv bottom yzplane
		if (rank != neighbors[3]) MPI_Recv(&local_array[local_size[0]+1][1][1], 1, yzplane, neighbors[3], 0, comm, &status);

		// send bottom yzplane
		if (rank != neighbors[3]) MPI_Send(&local_array[local_size[0]][1][1], 1, yzplane, neighbors[3], 0, comm);
		// recv top yzplane
		if (rank != neighbors[0]) MPI_Recv(&local_array[0][1][1], 1, yzplane, neighbors[0], 0, comm, &status);

		// send left xzplane
		if (rank != neighbors[1]) MPI_Send(&local_array[1][1][1], 1, xzplane, neighbors[1], 0, comm);
		// recv right xzplane
		if (rank != neighbors[2]) MPI_Recv(&local_array[1][local_size[1]+1][1], 1, xzplane, neighbors[2], 0, comm, &status);

		// send right xzplane
		if (rank != neighbors[2]) MPI_Send(&local_array[1][local_size[1]][1], 1, xzplane, neighbors[2], 0, comm);
		// recv left xzplane
		if (rank != neighbors[1]) MPI_Recv(&local_array[1][0][1], 1, xzplane, neighbors[1], 0, comm, &status);

		// send front xyplane
		if (rank != neighbors[4]) MPI_Send(&local_array[1][1][1], 1, xyplane, neighbors[4], 0, comm);
		// recv back xyplane
		if (rank != neighbors[5]) MPI_Recv(&local_array[1][1][local_size[2]+1], 1, xyplane, neighbors[5], 0, comm, &status);

		// send back xyplane
		if (rank != neighbors[5]) MPI_Send(&local_array[1][1][local_size[2]], 1, xyplane, neighbors[5], 0, comm);
		// recv front xyplane
		if (rank != neighbors[4]) MPI_Recv(&local_array[1][1][0], 1, xyplane, neighbors[4], 0, comm, &status);

//		if (rank==0) {
//		for(row=0; row<mem_size[0]; row++) {
//			for(col=0; col<mem_size[1]; col++) {
//				for(pln=0; pln<mem_size[2]; pln++) {
//					printf("%c", local_array[row][col][pln]);
//				}
//				printf("\n");
//			}
//			printf("-----------------------\n");
//		}
//		}
		
		// run the game of life
		
		// gameOfLife(local_array, local_array_copy, local_size[0], local_size[1], l, rank);
		
		// swap the arrays
		
//		temp1 = local_array;
//		local_array = local_array_copy;
//		local_array_copy = temp1;
//
//		temp2 = local_array_pointer;
//		local_array_pointer = local_array_copy_pointer;
//		local_array_copy_pointer = temp2;		
	
		// check to see if this iteration needs a checkpoint
		
		kCounter--;
		if (kCounter == 0) {
			kCounter = k;
			
			// checkpoint code
			
			MPI_File_open(MPI_COMM_WORLD, CHECKPOINT, MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
			MPI_File_set_view(fh, 0, MPI_CHAR, filetype, "native", MPI_INFO_NULL);
			
			MPI_File_write_all(fh, local_array_pointer, 1, memtype, &status);
			
			MPI_File_close(&fh); 	

			if (rank == 0)
				printf("Checkpoint made: Iteration %d\n", iterations+1);
			
		} // end if kCounter == 0 
	} // end iteration loop	
	iterations--;
	
	// all done! repeat the checkpoint process
	
	MPI_File_open(MPI_COMM_WORLD, FINAL_RESULTS, MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
	MPI_File_set_view(fh, 0, MPI_CHAR, filetype, "native", MPI_INFO_NULL);
	
	MPI_File_write_all(fh, local_array_pointer, 1, memtype, &status);
	
	MPI_File_close(&fh); 	

	if (rank == 0)
		printf("Final Results made: Iteration %d\n", iterations+1);
	
	time2 = MPI_Wtime();
	if (rank == 0)
	    printf("Elapsed Seconds: %f\n", time2-time1);fflush(stdout);
	
	MPI_Finalize(); 
	return EXIT_SUCCESS; 
}
Exemple #12
0
int main(int argc, char **argv)
{
    int *writebuf, *readbuf, i, mynod, nprocs, len, err;
    char *filename;
    int errs=0, toterrs;
    MPI_Datatype newtype;
    MPI_File fh;
    MPI_Status status;
    MPI_Info info;

    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &mynod);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

/* process 0 takes the file name as a command-line argument and
   broadcasts it to other processes */
    if (!mynod) {
	i = 1;
	while ((i < argc) && strcmp("-fname", *argv)) {
	    i++;
	    argv++;
	}
	if (i >= argc) {
	    fprintf(stderr, "\n*#  Usage: coll_test -fname filename\n\n");
	    MPI_Abort(MPI_COMM_WORLD, 1);
	}
	argv++;
	len = strlen(*argv);
	filename = (char *) malloc(len+1);
	strcpy(filename, *argv);
	MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
	MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
    }
    else {
	MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
	filename = (char *) malloc(len+1);
	MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
    }

    writebuf = (int *) malloc(BUFSIZE*sizeof(int));
    readbuf = (int *) malloc(BUFSIZE*sizeof(int));

/* test atomicity of contiguous accesses */

/* initialize file to all zeros */
    if (!mynod) {
	MPI_File_delete(filename, MPI_INFO_NULL);
	MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_CREATE |
             MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
	for (i=0; i<BUFSIZE; i++) writebuf[i] = 0;
	MPI_File_write(fh, writebuf, BUFSIZE, MPI_INT, &status);
	MPI_File_close(&fh);
#if VERBOSE
	fprintf(stderr, "\ntesting contiguous accesses\n");
#endif
    }
    MPI_Barrier(MPI_COMM_WORLD);

    for (i=0; i<BUFSIZE; i++) writebuf[i] = 10;
    for (i=0; i<BUFSIZE; i++) readbuf[i] = 20;

    MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE |
             MPI_MODE_RDWR, MPI_INFO_NULL, &fh);

/* set atomicity to true */
    err = MPI_File_set_atomicity(fh, 1);
    if (err != MPI_SUCCESS) {
	fprintf(stderr, "Atomic mode not supported on this file system.\n");fflush(stderr);
	MPI_Abort(MPI_COMM_WORLD, 1);
    }

    MPI_Barrier(MPI_COMM_WORLD);

/* process 0 writes and others concurrently read. In atomic mode,
   the data read must be either all old values or all new values; nothing
   in between. */

    if (!mynod) MPI_File_write(fh, writebuf, BUFSIZE, MPI_INT, &status);
    else {
	err = MPI_File_read(fh, readbuf, BUFSIZE, MPI_INT, &status);
	if (err == MPI_SUCCESS) {
	    if (readbuf[0] == 0) { /* the rest must also be 0 */
		for (i=1; i<BUFSIZE; i++)
		    if (readbuf[i] != 0) {
			errs++;
			fprintf(stderr, "Process %d: readbuf[%d] is %d, should be 0\n", mynod, i, readbuf[i]);
			MPI_Abort(MPI_COMM_WORLD, 1);
		    }
	    }
	    else if (readbuf[0] == 10) { /* the rest must also be 10 */
		for (i=1; i<BUFSIZE; i++)
		    if (readbuf[i] != 10) {
			errs++;
			fprintf(stderr, "Process %d: readbuf[%d] is %d, should be 10\n", mynod, i, readbuf[i]);
			MPI_Abort(MPI_COMM_WORLD, 1);
		    }
	    }
	    else {
		errs++;
		fprintf(stderr, "Process %d: readbuf[0] is %d, should be either 0 or 10\n", mynod, readbuf[0]);
	    }
	}
    }

    MPI_File_close(&fh);

    MPI_Barrier(MPI_COMM_WORLD);


/* repeat the same test with a noncontiguous filetype */

    MPI_Type_vector(BUFSIZE, 1, 2, MPI_INT, &newtype);
    MPI_Type_commit(&newtype);

    MPI_Info_create(&info);
    /* I am setting these info values for testing purposes only. It is
       better to use the default values in practice. */
    MPI_Info_set(info, "ind_rd_buffer_size", "1209");
    MPI_Info_set(info, "ind_wr_buffer_size", "1107");

    if (!mynod) {
	MPI_File_delete(filename, MPI_INFO_NULL);
	MPI_File_open(MPI_COMM_SELF, filename, MPI_MODE_CREATE |
             MPI_MODE_RDWR, info, &fh);
	for (i=0; i<BUFSIZE; i++) writebuf[i] = 0;
	MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
	MPI_File_write(fh, writebuf, BUFSIZE, MPI_INT, &status);
	MPI_File_close(&fh);
#if VERBOSE
	fprintf(stderr, "\ntesting noncontiguous accesses\n");
#endif
    }
    MPI_Barrier(MPI_COMM_WORLD);

    for (i=0; i<BUFSIZE; i++) writebuf[i] = 10;
    for (i=0; i<BUFSIZE; i++) readbuf[i] = 20;

    MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE |
             MPI_MODE_RDWR, info, &fh);
    MPI_File_set_atomicity(fh, 1);
    MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);
    MPI_Barrier(MPI_COMM_WORLD);

    if (!mynod) MPI_File_write(fh, writebuf, BUFSIZE, MPI_INT, &status);
    else {
	err = MPI_File_read(fh, readbuf, BUFSIZE, MPI_INT, &status);
	if (err == MPI_SUCCESS) {
	    if (readbuf[0] == 0) {
		for (i=1; i<BUFSIZE; i++)
		    if (readbuf[i] != 0) {
			errs++;
			fprintf(stderr, "Process %d: readbuf[%d] is %d, should be 0\n", mynod, i, readbuf[i]);
			MPI_Abort(MPI_COMM_WORLD, 1);
		    }
	    }
	    else if (readbuf[0] == 10) {
		for (i=1; i<BUFSIZE; i++)
		    if (readbuf[i] != 10) {
			errs++;
			fprintf(stderr, "Process %d: readbuf[%d] is %d, should be 10\n", mynod, i, readbuf[i]);
			MPI_Abort(MPI_COMM_WORLD, 1);
		    }
	    }
	    else {
		errs++;
		fprintf(stderr, "Process %d: readbuf[0] is %d, should be either 0 or 10\n", mynod, readbuf[0]);
	    }
	}
    }

    MPI_File_close(&fh);

    MPI_Barrier(MPI_COMM_WORLD);

    MPI_Allreduce( &errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
    if (mynod == 0) {
	if( toterrs > 0) {
	    fprintf( stderr, "Found %d errors\n", toterrs );
	}
	else {
	    fprintf( stdout, " No Errors\n" );
	}
    }
    MPI_Type_free(&newtype);
    MPI_Info_free(&info);
    free(writebuf);
    free(readbuf);
    free(filename);

    MPI_Finalize();
    return 0;
}
Exemple #13
0
void writetofile(int rank, int a)
{
#if defined(MPI) && defined(FILEIMAGE)
    // dump all the tiles to 1 file using MPI-IO
    int color = 0;
    MPI_Comm tilecomm;
    MPI_File  fhtout;
    if (owneroftile == rank) color = 1;
    PRINTDEBUG("%3d: tileowner=%d, color=%d\n", rank, owneroftile, color);
    MPI_Comm_split(MPI_COMM_WORLD, color, rank, &tilecomm);
    if (color) {
        int cartrank;
        MPI_Comm cartcomm;
        const MPI_Status status;
        // init parameters for Cart_create
        int gsizes[2] = {viewport.h, viewport.w*ELEMENTSPERPIXEL};
        int psizes[2] = {viewport.tiley, viewport.tilex};
        int lsizes[2] = {gsizes[0]/psizes[0], (gsizes[1])/psizes[1]};
        int dims[2] = {psizes[0], psizes[1]};
        int periods[2] = {1,1};
        int coords[2];
        PRINTDEBUG("%3d: gsizes=%d,%d, psizes=%d,%d, lsizes=%d,%d\n", rank, gsizes[0], gsizes[1], psizes[0], psizes[1],
                   lsizes[0], lsizes[1]);
        // Create cartesian coord
        MPI_Cart_create(tilecomm, 2, dims, periods, 0, &cartcomm);
        MPI_Comm_rank(cartcomm, &cartrank);
        MPI_Cart_coords(cartcomm, cartrank, 2, coords);
        // check coords
        PRINTDEBUG("%3d: coords=%d,%d\n", cartrank, coords[0], coords[1]);

        /* global indices of first element of local array */
        int startindex[2];
        startindex[0] = coords[0] * lsizes[0];
        startindex[1] = coords[1] * lsizes[1];

        PRINTDEBUG("%3d: start=%d,%d\n", cartrank, startindex[0], startindex[1]);
        int filetype;
        filetype=0;
        MPI_Type_create_subarray(2, gsizes, lsizes, startindex, MPI_ORDER_C, MPI_FLOAT, &filetype);
        MPI_Type_commit(&filetype);

        char imagefull[32];
        sprintf(imagefull,"imagefull%d.raw", a);
        PRINTDEBUG("%s\n", imagefull);
        MPI_File_open(cartcomm, imagefull, MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &fhtout);
        MPI_File_set_view(fhtout, 0, MPI_FLOAT, filetype, "native", MPI_INFO_NULL);
        int localarraysize = lsizes[0] * lsizes[1];
        PRINTDEBUG("%3d: size=%d\n", cartrank, localarraysize);

        MPI_File_write(fhtout, tilebuffer, localarraysize, MPI_FLOAT, &status);
        int count;
        MPI_Get_count(&status, MPI_FLOAT, &count);
        PRINTDEBUG("%3d: cnt=%d\n", cartrank, count);
        MPI_File_close(&fhtout);
        MPI_Comm_free(&cartcomm);
        MPI_Type_free(&filetype);
//		free(tilebuffer);
    }
    MPI_Comm_free(&tilecomm);
#endif
}
int run_test (test_param_t *test) {
    ADIO_Offset st_offset, end_offset;
    MPI_File fh;
    int is_contig;
    int ind_err = 0, exp_err = 0;

    MPI_Datatype filetype;

    MPI_Type_struct (test->type_count, test->type_blocklens,
		     test->type_indices, test->type_oldtypes, &filetype);
    MPI_Type_commit (&filetype);

    MPI_File_open (MPI_COMM_WORLD, "test_file.txt" , MPI_MODE_RDWR,
		   MPI_INFO_NULL, &fh);

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

    MPI_File_seek (fh, test->offset, MPI_SEEK_SET);
    ADIOI_Calc_bounds ((ADIO_File) fh, test->count, MPI_BYTE, ADIO_INDIVIDUAL,
		       test->offset, &st_offset, &end_offset);    

    ind_err = 0;
    if (st_offset != test->correct_st_offset) {
	printf ("Individual st_offset = %lld end_offset = %lld\n",
		st_offset, end_offset);
	ind_err = 1;
    }
    if (end_offset != test->correct_end_offset) {
	printf ("Individual st_offset = %lld end_offset = %lld\n",
		st_offset, end_offset);
	ind_err = 1;
    }
    MPI_File_close (&fh);
    if (ind_err)
	printf ("Individual Calc FAILED\n");

    MPI_File_open (MPI_COMM_WORLD, "test_file.txt" , MPI_MODE_RDWR,
		   MPI_INFO_NULL, &fh);

    if (!is_contig)
	MPI_File_set_view (fh, 0, MPI_BYTE, filetype, "native", MPI_INFO_NULL);

    MPI_File_seek (fh, 0, MPI_SEEK_SET);
    ADIOI_Calc_bounds ((ADIO_File) fh, test->count, MPI_BYTE,
		       ADIO_EXPLICIT_OFFSET, test->offset, &st_offset,
		       &end_offset);

    exp_err = 0;
    if (st_offset != test->correct_st_offset) {
	printf ("Explicit   st_offset = %lld end_offset = %lld\n",
		st_offset, end_offset);
	exp_err = 1;
    }
    if (end_offset != test->correct_end_offset) {
	printf ("Explicit   st_offset = %lld end_offset = %lld\n",
		st_offset, end_offset);
	exp_err = 1;
    }
    if (exp_err)
	printf ("Explicit Calc FAILED\n");

    MPI_File_close (&fh);

    if (!is_contig)
	MPI_Type_free (&filetype);

    return (exp_err || ind_err);
}
Exemple #15
0
int main(int argc, char **argv)
{
    int *buf, i, mynod, nprocs, len, b[3];
    int errs=0, toterrs;
    MPI_Aint d[3];
    MPI_File fh;
    MPI_Status status;
    char *filename;
    MPI_Datatype typevec, newtype, t[3];
    MPI_Info info;

    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &mynod);

    if (nprocs != 2) {
        fprintf(stderr, "Run this program on two processes\n");
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

/* process 0 takes the file name as a command-line argument and
   broadcasts it to other processes (length first, then string) */
    if (!mynod) {
	i = 1;
	while ((i < argc) && strcmp("-fname", *argv)) {
	    i++;
	    argv++;
	}
	if (i >= argc) {
	    fprintf(stderr, "\n*#  Usage: noncontig -fname filename\n\n");
	    MPI_Abort(MPI_COMM_WORLD, 1);
	}
	argv++;
	len = strlen(*argv);
	filename = (char *) malloc(len+1);
	strcpy(filename, *argv);
	MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
	MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
    }
    else {
	MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
	filename = (char *) malloc(len+1);
	MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD);
    }

    buf = (int *) malloc(SIZE*sizeof(int));

    MPI_Type_vector(SIZE/2, 1, 2, MPI_INT, &typevec);

    /* create a struct type with explicitly set LB and UB; displacements
     * of typevec are such that the types for the two processes won't
     * overlap.
     */
    b[0] = b[1] = b[2] = 1;
    d[0] = 0;
    d[1] = mynod*sizeof(int);
    d[2] = SIZE*sizeof(int);
    t[0] = MPI_LB;
    t[1] = typevec;
    t[2] = MPI_UB;

    /* keep the struct, ditch the vector */
    MPI_Type_struct(3, b, d, t, &newtype);
    MPI_Type_commit(&newtype);
    MPI_Type_free(&typevec);

    MPI_Info_create(&info);
    /* I am setting these info values for testing purposes only. It is
       better to use the default values in practice. */
    MPI_Info_set(info, "ind_rd_buffer_size", "1209");
    MPI_Info_set(info, "ind_wr_buffer_size", "1107");

    if (!mynod) {
#if VERBOSE
	fprintf(stderr, "\ntesting noncontiguous in memory, noncontiguous in file using independent I/O\n");
#endif
	MPI_File_delete(filename, MPI_INFO_NULL);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
                  info, &fh);

    /* set the file view for each process -- now writes go into the non-
     * overlapping but interleaved region defined by the struct type up above
     */
    MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);

    /* fill our buffer with a pattern and write, using our type again */
    for (i=0; i<SIZE; i++) buf[i] = i + mynod*SIZE;
    MPI_File_write(fh, buf, 1, newtype, &status);

    MPI_Barrier(MPI_COMM_WORLD);

    /* fill the entire buffer with -1's.  read back with type.
     * note that the result of this read should be that every other value
     * in the buffer is still -1, as defined by our type.
     */
    for (i=0; i<SIZE; i++) buf[i] = -1;
    MPI_File_read_at(fh, 0, buf, 1, newtype, &status);

    /* check that all the values read are correct and also that we didn't
     * overwrite any of the -1 values that we shouldn't have.
     */
    for (i=0; i<SIZE; i++) {
	if (!mynod) {
	    if ((i%2) && (buf[i] != -1)) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
			mynod, i, buf[i]);
	    }
	    if (!(i%2) && (buf[i] != i)) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
			mynod, i, buf[i], i);
	    }
	}
	else {
	    if ((i%2) && (buf[i] != i + mynod*SIZE)) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
			mynod, i, buf[i], i + mynod*SIZE);
	    }
	    if (!(i%2) && (buf[i] != -1)) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
			mynod, i, buf[i]);
	    }
	}
    }

    MPI_File_close(&fh);

    MPI_Barrier(MPI_COMM_WORLD);

    if (!mynod) {
#if VERBOSE
	fprintf(stderr, "\ntesting noncontiguous in memory, contiguous in file using independent I/O\n");
#endif
	MPI_File_delete(filename, MPI_INFO_NULL);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
                  info, &fh);

    /* in this case we write to either the first half or the second half
     * of the file space, so the regions are not interleaved.  this is done
     * by leaving the file view at its default.
     */
    for (i=0; i<SIZE; i++) buf[i] = i + mynod*SIZE;
    MPI_File_write_at(fh, mynod*(SIZE/2)*sizeof(int), buf, 1, newtype, &status);

    MPI_Barrier(MPI_COMM_WORLD);

    /* same as before; fill buffer with -1's and then read; every other
     * value should still be -1 after the read
     */
    for (i=0; i<SIZE; i++) buf[i] = -1;
    MPI_File_read_at(fh, mynod*(SIZE/2)*sizeof(int), buf, 1, newtype, &status);

    /* verify that the buffer looks like it should */
    for (i=0; i<SIZE; i++) {
	if (!mynod) {
	    if ((i%2) && (buf[i] != -1)) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
			mynod, i, buf[i]);
	    }
	    if (!(i%2) && (buf[i] != i)) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
			mynod, i, buf[i], i);
	    }
	}
	else {
	    if ((i%2) && (buf[i] != i + mynod*SIZE)) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
			mynod, i, buf[i], i + mynod*SIZE);
	    }
	    if (!(i%2) && (buf[i] != -1)) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be -1\n",
			mynod, i, buf[i]);
	    }
	}
    }

    MPI_File_close(&fh);

    MPI_Barrier(MPI_COMM_WORLD);

    if (!mynod) {
#if VERBOSE
	fprintf(stderr, "\ntesting contiguous in memory, noncontiguous in file using independent I/O\n");
#endif
	MPI_File_delete(filename, MPI_INFO_NULL);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR,
                  info, &fh);

    /* set the file view so that we have interleaved access again */
    MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info);

    /* this time write a contiguous buffer */
    for (i=0; i<SIZE; i++) buf[i] = i + mynod*SIZE;
    MPI_File_write(fh, buf, SIZE, MPI_INT, &status);

    MPI_Barrier(MPI_COMM_WORLD);

    /* fill buffer with -1's; this time they will all be overwritten */
    for (i=0; i<SIZE; i++) buf[i] = -1;
    MPI_File_read_at(fh, 0, buf, SIZE, MPI_INT, &status);

    for (i=0; i<SIZE; i++) {
	if (!mynod) {
	    if (buf[i] != i) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
			mynod, i, buf[i], i);
	    }
	}
	else {
	    if (buf[i] != i + mynod*SIZE) {
		errs++;
		fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
			mynod, i, buf[i], i + mynod*SIZE);
	    }
	}
    }

    MPI_File_close(&fh);

    MPI_Allreduce( &errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
    if (mynod == 0) {
	if( toterrs > 0) {
	    fprintf( stderr, "Found %d errors\n", toterrs );
	}
	else {
	    fprintf( stdout, " No Errors\n" );
	}
    }
    MPI_Type_free(&newtype);
    MPI_Info_free(&info);
    free(buf);
    free(filename);
    MPI_Finalize();
    return 0;
}
Exemple #16
0
/*
 * Open a file through the MPIIO interface.  Setup file view.
 */
static void *MPIIO_Open(char *testFileName, IOR_param_t * param)
{
        int fd_mode = (int)0,
            offsetFactor,
            tasksPerFile,
            transfersPerBlock = param->blockSize / param->transferSize;
        struct fileTypeStruct {
                int globalSizes[2], localSizes[2], startIndices[2];
        } fileTypeStruct;
        MPI_File *fd;
        MPI_Comm comm;
        MPI_Info mpiHints = MPI_INFO_NULL;

        fd = (MPI_File *) malloc(sizeof(MPI_File));
        if (fd == NULL)
                ERR("malloc failed()");

        *fd = 0;

        /* set IOR file flags to MPIIO flags */
        /* -- file open flags -- */
        if (param->openFlags & IOR_RDONLY) {
                fd_mode |= MPI_MODE_RDONLY;
        }
        if (param->openFlags & IOR_WRONLY) {
                fd_mode |= MPI_MODE_WRONLY;
        }
        if (param->openFlags & IOR_RDWR) {
                fd_mode |= MPI_MODE_RDWR;
        }
        if (param->openFlags & IOR_APPEND) {
                fd_mode |= MPI_MODE_APPEND;
        }
        if (param->openFlags & IOR_CREAT) {
                fd_mode |= MPI_MODE_CREATE;
        }
        if (param->openFlags & IOR_EXCL) {
                fd_mode |= MPI_MODE_EXCL;
        }
        if (param->openFlags & IOR_TRUNC) {
                fprintf(stdout, "File truncation not implemented in MPIIO\n");
        }
        if (param->openFlags & IOR_DIRECT) {
                fprintf(stdout, "O_DIRECT not implemented in MPIIO\n");
        }

        /*
         * MPI_MODE_UNIQUE_OPEN mode optimization eliminates the overhead of file
         * locking.  Only open a file in this mode when the file will not be con-
         * currently opened elsewhere, either inside or outside the MPI environment.
         */
        fd_mode |= MPI_MODE_UNIQUE_OPEN;

        if (param->filePerProc) {
                comm = MPI_COMM_SELF;
        } else {
                comm = testComm;
        }

        SetHints(&mpiHints, param->hintsFileName);
        /*
         * note that with MP_HINTS_FILTERED=no, all key/value pairs will
         * be in the info object.  The info object that is attached to
         * the file during MPI_File_open() will only contain those pairs
         * deemed valid by the implementation.
         */
        /* show hints passed to file */
        if (rank == 0 && param->showHints) {
                fprintf(stdout, "\nhints passed to MPI_File_open() {\n");
                ShowHints(&mpiHints);
                fprintf(stdout, "}\n");
        }
        MPI_CHECK(MPI_File_open(comm, testFileName, fd_mode, mpiHints, fd),
                  "cannot open file");

        /* show hints actually attached to file handle */
        if (rank == 0 && param->showHints) {
                MPI_CHECK(MPI_File_get_info(*fd, &mpiHints),
                          "cannot get file info");
                fprintf(stdout, "\nhints returned from opened file {\n");
                ShowHints(&mpiHints);
                fprintf(stdout, "}\n");
        }

        /* preallocate space for file */
        if (param->preallocate && param->open == WRITE) {
                MPI_CHECK(MPI_File_preallocate(*fd,
                                               (MPI_Offset) (param->segmentCount
                                                             *
                                                             param->blockSize *
                                                             param->numTasks)),
                          "cannot preallocate file");
        }
        /* create file view */
        if (param->useFileView) {
                /* create contiguous transfer datatype */
                MPI_CHECK(MPI_Type_contiguous
                          (param->transferSize / sizeof(IOR_size_t),
                           MPI_LONG_LONG_INT, &param->transferType),
                          "cannot create contiguous datatype");
                MPI_CHECK(MPI_Type_commit(&param->transferType),
                          "cannot commit datatype");
                if (param->filePerProc) {
                        offsetFactor = 0;
                        tasksPerFile = 1;
                } else {
                        offsetFactor = (rank + rankOffset) % param->numTasks;
                        tasksPerFile = param->numTasks;
                }

                /*
                 * create file type using subarray
                 */
                fileTypeStruct.globalSizes[0] = 1;
                fileTypeStruct.globalSizes[1] =
                    transfersPerBlock * tasksPerFile;
                fileTypeStruct.localSizes[0] = 1;
                fileTypeStruct.localSizes[1] = transfersPerBlock;
                fileTypeStruct.startIndices[0] = 0;
                fileTypeStruct.startIndices[1] =
                    transfersPerBlock * offsetFactor;

                MPI_CHECK(MPI_Type_create_subarray
                          (2, fileTypeStruct.globalSizes,
                           fileTypeStruct.localSizes,
                           fileTypeStruct.startIndices, MPI_ORDER_C,
                           param->transferType, &param->fileType),
                          "cannot create subarray");
                MPI_CHECK(MPI_Type_commit(&param->fileType),
                          "cannot commit datatype");

                MPI_CHECK(MPI_File_set_view(*fd, (MPI_Offset) 0,
                                            param->transferType,
                                            param->fileType, "native",
                                            (MPI_Info) MPI_INFO_NULL),
                          "cannot set file view");
        }
        return ((void *)fd);
}
Exemple #17
0
int main(int argc, char** argv) {
  MPI_Init(&argc, &argv);

  setup_globals();

  /* Parse arguments. */
  int SCALE = 16;
  int edgefactor = 16; /* nedges / nvertices, i.e., 2*avg. degree */
  int energytime = 0;
  if (argc >= 2) SCALE = atoi(argv[1]);
  if (argc >= 3) edgefactor = atoi(argv[2]);
  if (argc >= 4) energytime = atoi(argv[3]);
  if (argc <= 1 || argc >= 5 || SCALE == 0 || edgefactor == 0) {
    if (rank == 0) {
      fprintf(stderr, "Usage: %s SCALE edgefactor energytime\n  SCALE = log_2(# vertices) [integer, required]\n  edgefactor = (# edges) / (# vertices) = .5 * (average vertex degree) [integer, defaults to 16]\n  energytime = time to run the energy benchmark (will print markers) [integer, seconds, defaults to 0]\n(Random number seed and Kronecker initiator are in main.c)\n", argv[0]);
    }
    MPI_Abort(MPI_COMM_WORLD, 1);
  }
  uint64_t seed1 = 2, seed2 = 3;

  const char* filename = getenv("TMPFILE");
  /* If filename is NULL, store data in memory */

  tuple_graph tg;
  tg.nglobaledges = (int64_t)(edgefactor) << SCALE;
  int64_t nglobalverts = (int64_t)(1) << SCALE;

  tg.data_in_file = (filename != NULL);

  if (tg.data_in_file) {
    MPI_File_set_errhandler(MPI_FILE_NULL, MPI_ERRORS_ARE_FATAL);
    MPI_File_open(MPI_COMM_WORLD, (char*)filename, MPI_MODE_RDWR | MPI_MODE_CREATE | MPI_MODE_EXCL | MPI_MODE_DELETE_ON_CLOSE | MPI_MODE_UNIQUE_OPEN, MPI_INFO_NULL, &tg.edgefile);
    MPI_File_set_size(tg.edgefile, tg.nglobaledges * sizeof(packed_edge));
    MPI_File_set_view(tg.edgefile, 0, packed_edge_mpi_type, packed_edge_mpi_type, "native", MPI_INFO_NULL);
    MPI_File_set_atomicity(tg.edgefile, 0);
  }

  /* Make the raw graph edges. */
  /* Get roots for BFS runs, plus maximum vertex with non-zero degree (used by
   * validator). */
  int num_bfs_roots = 64;
  int64_t* bfs_roots = (int64_t*)xmalloc(num_bfs_roots * sizeof(int64_t));
  int64_t max_used_vertex = 0;

  double make_graph_start = MPI_Wtime();
  {
    /* Spread the two 64-bit numbers into five nonzero values in the correct
     * range. */
    uint_fast32_t seed[5];
    make_mrg_seed(seed1, seed2, seed);

    /* As the graph is being generated, also keep a bitmap of vertices with
     * incident edges.  We keep a grid of processes, each row of which has a
     * separate copy of the bitmap (distributed among the processes in the
     * row), and then do an allreduce at the end.  This scheme is used to avoid
     * non-local communication and reading the file separately just to find BFS
     * roots. */
    MPI_Offset nchunks_in_file = (tg.nglobaledges + FILE_CHUNKSIZE - 1) / FILE_CHUNKSIZE;
    int64_t bitmap_size_in_bytes = int64_min(BITMAPSIZE, (nglobalverts + CHAR_BIT - 1) / CHAR_BIT);
    if (bitmap_size_in_bytes * size * CHAR_BIT < nglobalverts) {
      bitmap_size_in_bytes = (nglobalverts + size * CHAR_BIT - 1) / (size * CHAR_BIT);
    }
    int ranks_per_row = ((nglobalverts + CHAR_BIT - 1) / CHAR_BIT + bitmap_size_in_bytes - 1) / bitmap_size_in_bytes;
    int nrows = size / ranks_per_row;
    int my_row = -1, my_col = -1;
    unsigned char* restrict has_edge = NULL;
    MPI_Comm cart_comm;
    {
      int dims[2] = {size / ranks_per_row, ranks_per_row};
      int periods[2] = {0, 0};
      MPI_Cart_create(MPI_COMM_WORLD, 2, dims, periods, 1, &cart_comm);
    }
    int in_generating_rectangle = 0;
    if (cart_comm != MPI_COMM_NULL) {
      in_generating_rectangle = 1;
      {
        int dims[2], periods[2], coords[2];
        MPI_Cart_get(cart_comm, 2, dims, periods, coords);
        my_row = coords[0];
        my_col = coords[1];
      }
      MPI_Comm this_col;
      MPI_Comm_split(cart_comm, my_col, my_row, &this_col);
      MPI_Comm_free(&cart_comm);
      has_edge = (unsigned char*)xMPI_Alloc_mem(bitmap_size_in_bytes);
      memset(has_edge, 0, bitmap_size_in_bytes);
      /* Every rank in a given row creates the same vertices (for updating the
       * bitmap); only one writes them to the file (or final memory buffer). */
      packed_edge* buf = (packed_edge*)xmalloc(FILE_CHUNKSIZE * sizeof(packed_edge));
      MPI_Offset block_limit = (nchunks_in_file + nrows - 1) / nrows;
      /* fprintf(stderr, "%d: nchunks_in_file = %" PRId64 ", block_limit = %" PRId64 " in grid of %d rows, %d cols\n", rank, (int64_t)nchunks_in_file, (int64_t)block_limit, nrows, ranks_per_row); */
      if (tg.data_in_file) {
        tg.edgememory_size = 0;
        tg.edgememory = NULL;
      } else {
        int my_pos = my_row + my_col * nrows;
        int last_pos = (tg.nglobaledges % ((int64_t)FILE_CHUNKSIZE * nrows * ranks_per_row) != 0) ?
                       (tg.nglobaledges / FILE_CHUNKSIZE) % (nrows * ranks_per_row) :
                       -1;
        int64_t edges_left = tg.nglobaledges % FILE_CHUNKSIZE;
        int64_t nedges = FILE_CHUNKSIZE * (tg.nglobaledges / ((int64_t)FILE_CHUNKSIZE * nrows * ranks_per_row)) +
                         FILE_CHUNKSIZE * (my_pos < (tg.nglobaledges / FILE_CHUNKSIZE) % (nrows * ranks_per_row)) +
                         (my_pos == last_pos ? edges_left : 0);
        /* fprintf(stderr, "%d: nedges = %" PRId64 " of %" PRId64 "\n", rank, (int64_t)nedges, (int64_t)tg.nglobaledges); */
        tg.edgememory_size = nedges;
        tg.edgememory = (packed_edge*)xmalloc(nedges * sizeof(packed_edge));
      }
      MPI_Offset block_idx;
      for (block_idx = 0; block_idx < block_limit; ++block_idx) {
        /* fprintf(stderr, "%d: On block %d of %d\n", rank, (int)block_idx, (int)block_limit); */
        MPI_Offset start_edge_index = int64_min(FILE_CHUNKSIZE * (block_idx * nrows + my_row), tg.nglobaledges);
        MPI_Offset edge_count = int64_min(tg.nglobaledges - start_edge_index, FILE_CHUNKSIZE);
        packed_edge* actual_buf = (!tg.data_in_file && block_idx % ranks_per_row == my_col) ?
                                  tg.edgememory + FILE_CHUNKSIZE * (block_idx / ranks_per_row) :
                                  buf;
        /* fprintf(stderr, "%d: My range is [%" PRId64 ", %" PRId64 ") %swriting into index %" PRId64 "\n", rank, (int64_t)start_edge_index, (int64_t)(start_edge_index + edge_count), (my_col == (block_idx % ranks_per_row)) ? "" : "not ", (int64_t)(FILE_CHUNKSIZE * (block_idx / ranks_per_row))); */
        if (!tg.data_in_file && block_idx % ranks_per_row == my_col) {
          assert (FILE_CHUNKSIZE * (block_idx / ranks_per_row) + edge_count <= tg.edgememory_size);
        }
        generate_kronecker_range(seed, SCALE, start_edge_index, start_edge_index + edge_count, actual_buf);
        if (tg.data_in_file && my_col == (block_idx % ranks_per_row)) { /* Try to spread writes among ranks */
          MPI_File_write_at(tg.edgefile, start_edge_index, actual_buf, edge_count, packed_edge_mpi_type, MPI_STATUS_IGNORE);
        }
        ptrdiff_t i;
#ifdef _OPENMP
#pragma omp parallel for
#endif
        for (i = 0; i < edge_count; ++i) {
          int64_t src = get_v0_from_edge(&actual_buf[i]);
          int64_t tgt = get_v1_from_edge(&actual_buf[i]);
          if (src == tgt) continue;
          if (src / bitmap_size_in_bytes / CHAR_BIT == my_col) {
#ifdef _OPENMP
#pragma omp atomic
#endif
            has_edge[(src / CHAR_BIT) % bitmap_size_in_bytes] |= (1 << (src % CHAR_BIT));
          }
          if (tgt / bitmap_size_in_bytes / CHAR_BIT == my_col) {
#ifdef _OPENMP
#pragma omp atomic
#endif
            has_edge[(tgt / CHAR_BIT) % bitmap_size_in_bytes] |= (1 << (tgt % CHAR_BIT));
          }
        }
      }
      free(buf);
#if 0
      /* The allreduce for each root acts like we did this: */
      MPI_Allreduce(MPI_IN_PLACE, has_edge, bitmap_size_in_bytes, MPI_UNSIGNED_CHAR, MPI_BOR, this_col);
#endif
      MPI_Comm_free(&this_col);
    } else {
      tg.edgememory = NULL;
      tg.edgememory_size = 0;
    }
    MPI_Allreduce(&tg.edgememory_size, &tg.max_edgememory_size, 1, MPI_INT64_T, MPI_MAX, MPI_COMM_WORLD);
    /* Find roots and max used vertex */
    {
      uint64_t counter = 0;
      int bfs_root_idx;
      for (bfs_root_idx = 0; bfs_root_idx < num_bfs_roots; ++bfs_root_idx) {
        int64_t root;
        while (1) {
          double d[2];
          make_random_numbers(2, seed1, seed2, counter, d);
          root = (int64_t)((d[0] + d[1]) * nglobalverts) % nglobalverts;
          counter += 2;
          if (counter > 2 * nglobalverts) break;
          int is_duplicate = 0;
          int i;
          for (i = 0; i < bfs_root_idx; ++i) {
            if (root == bfs_roots[i]) {
              is_duplicate = 1;
              break;
            }
          }
          if (is_duplicate) continue; /* Everyone takes the same path here */
          int root_ok = 0;
          if (in_generating_rectangle && (root / CHAR_BIT / bitmap_size_in_bytes) == my_col) {
            root_ok = (has_edge[(root / CHAR_BIT) % bitmap_size_in_bytes] & (1 << (root % CHAR_BIT))) != 0;
          }
          MPI_Allreduce(MPI_IN_PLACE, &root_ok, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD);
          if (root_ok) break;
        }
        bfs_roots[bfs_root_idx] = root;
      }
      num_bfs_roots = bfs_root_idx;

      /* Find maximum non-zero-degree vertex. */
      {
        int64_t i;
        max_used_vertex = 0;
        if (in_generating_rectangle) {
          for (i = bitmap_size_in_bytes * CHAR_BIT; i > 0; --i) {
            if (i > nglobalverts) continue;
            if (has_edge[(i - 1) / CHAR_BIT] & (1 << ((i - 1) % CHAR_BIT))) {
              max_used_vertex = (i - 1) + my_col * CHAR_BIT * bitmap_size_in_bytes;
              break;
            }
          }
        }
        MPI_Allreduce(MPI_IN_PLACE, &max_used_vertex, 1, MPI_INT64_T, MPI_MAX, MPI_COMM_WORLD);
      }
    }
    if (in_generating_rectangle) {
      MPI_Free_mem(has_edge);
    }
    if (tg.data_in_file) {
      MPI_File_sync(tg.edgefile);
    }
  }
  double make_graph_stop = MPI_Wtime();
  double make_graph_time = make_graph_stop - make_graph_start;
  if (rank == 0) { /* Not an official part of the results */
    fprintf(stderr, "graph_generation:               %f s\n", make_graph_time);
  }

  /* Make user's graph data structure. */
  double data_struct_start = MPI_Wtime();
  make_graph_data_structure(&tg);
  double data_struct_stop = MPI_Wtime();
  double data_struct_time = data_struct_stop - data_struct_start;
  if (rank == 0) { /* Not an official part of the results */
    fprintf(stderr, "construction_time:              %f s\n", data_struct_time);
  }

  /* Number of edges visited in each BFS; a double so get_statistics can be
   * used directly. */
  double* edge_counts = (double*)xmalloc(num_bfs_roots * sizeof(double));

  /* Run BFS. */
  int validation_passed = 1;
  double* bfs_times = (double*)xmalloc(num_bfs_roots * sizeof(double));
  double* validate_times = (double*)xmalloc(num_bfs_roots * sizeof(double));
  uint64_t nlocalverts = get_nlocalverts_for_pred();
  int64_t* pred = (int64_t*)xMPI_Alloc_mem(nlocalverts * sizeof(int64_t));

  /* energy measurement loop -- the following C block enables running
   * the benchmark for the specified time to conduct reasonable power
   * measurements for low-resolution devices. The code will print a
   * banner to stderr that enables to calibrate the power measurement.
   * The loop is run until the specified time expires. Make sure the
   * input is large enough to avoid caching! 
   * (c) Torsten Hoefler, ETH Zurich, direct questions to [email protected] */
  {
    double time_left=(double)energytime; /* energy measurement time left */
    int iters = 0;
    
    if(energytime > 0 && rank == 0) {
      time_t timestamp;
      time(&timestamp);
      fprintf(stderr, "Energy Benchmark Loop Starting on %s", ctime(&timestamp));
    }

    while(time_left > 0) {
      int bfs_root_idx;
        time_left += MPI_Wtime();
      for (bfs_root_idx = 0; bfs_root_idx < num_bfs_roots; ++bfs_root_idx) {
      int64_t root = bfs_roots[bfs_root_idx];

      /* Clear the pred array. */
      memset(pred, 0, nlocalverts * sizeof(int64_t));

      run_bfs(root, &pred[0]);
      }
      time_left -= MPI_Wtime();
      MPI_Bcast(&time_left, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
        iters++;
    }
    
    if(energytime > 0 && rank == 0) {
      time_t timestamp;
      time(&timestamp);
      fprintf(stderr, "Energy Benchmark Loop Finishing (%i iterations, %.6f per iteration) on %s", iters, (energytime-time_left)/num_bfs_roots/iters, ctime(&timestamp));
    }

  }
  /* end of modified code for power measurement */

  int bfs_root_idx;
  for (bfs_root_idx = 0; bfs_root_idx < num_bfs_roots; ++bfs_root_idx) {
    int64_t root = bfs_roots[bfs_root_idx];

    if (rank == 0) fprintf(stderr, "Running BFS %d\n", bfs_root_idx);

    /* Clear the pred array. */
    memset(pred, 0, nlocalverts * sizeof(int64_t));

    /* Do the actual BFS. */
    double bfs_start = MPI_Wtime();
    run_bfs(root, &pred[0]);
    double bfs_stop = MPI_Wtime();
    bfs_times[bfs_root_idx] = bfs_stop - bfs_start;
    if (rank == 0) fprintf(stderr, "Time for BFS %d is %f\n", bfs_root_idx, bfs_times[bfs_root_idx]);

    /* Validate result. */
    if (rank == 0) fprintf(stderr, "Validating BFS %d\n", bfs_root_idx);

    double validate_start = MPI_Wtime();
    int64_t edge_visit_count;
    int validation_passed_one = validate_bfs_result(&tg, max_used_vertex + 1, nlocalverts, root, pred, &edge_visit_count);
    double validate_stop = MPI_Wtime();
    validate_times[bfs_root_idx] = validate_stop - validate_start;
    if (rank == 0) fprintf(stderr, "Validate time for BFS %d is %f\n", bfs_root_idx, validate_times[bfs_root_idx]);
    edge_counts[bfs_root_idx] = (double)edge_visit_count;
    if (rank == 0) fprintf(stderr, "TEPS for BFS %d is %g\n", bfs_root_idx, edge_visit_count / bfs_times[bfs_root_idx]);

    if (!validation_passed_one) {
      validation_passed = 0;
      if (rank == 0) fprintf(stderr, "Validation failed for this BFS root; skipping rest.\n");
      break;
    }
  }

  MPI_Free_mem(pred);
  free(bfs_roots);
  free_graph_data_structure();

  if (tg.data_in_file) {
    MPI_File_close(&tg.edgefile);
  } else {
    free(tg.edgememory); tg.edgememory = NULL;
  }

  /* Print results. */
  if (rank == 0) {
    if (!validation_passed) {
      fprintf(stdout, "No results printed for invalid run.\n");
    } else {
      int i;
      fprintf(stdout, "SCALE:                          %d\n", SCALE);
      fprintf(stdout, "edgefactor:                     %d\n", edgefactor);
      fprintf(stdout, "NBFS:                           %d\n", num_bfs_roots);
      fprintf(stdout, "graph_generation:               %g\n", make_graph_time);
      fprintf(stdout, "num_mpi_processes:              %d\n", size);
      fprintf(stdout, "construction_time:              %g\n", data_struct_time);
      double stats[s_LAST];
      get_statistics(bfs_times, num_bfs_roots, stats);
      fprintf(stdout, "min_time:                       %g\n", stats[s_minimum]);
      fprintf(stdout, "firstquartile_time:             %g\n", stats[s_firstquartile]);
      fprintf(stdout, "median_time:                    %g\n", stats[s_median]);
      fprintf(stdout, "thirdquartile_time:             %g\n", stats[s_thirdquartile]);
      fprintf(stdout, "max_time:                       %g\n", stats[s_maximum]);
      fprintf(stdout, "mean_time:                      %g\n", stats[s_mean]);
      fprintf(stdout, "stddev_time:                    %g\n", stats[s_std]);
      get_statistics(edge_counts, num_bfs_roots, stats);
      fprintf(stdout, "min_nedge:                      %.11g\n", stats[s_minimum]);
      fprintf(stdout, "firstquartile_nedge:            %.11g\n", stats[s_firstquartile]);
      fprintf(stdout, "median_nedge:                   %.11g\n", stats[s_median]);
      fprintf(stdout, "thirdquartile_nedge:            %.11g\n", stats[s_thirdquartile]);
      fprintf(stdout, "max_nedge:                      %.11g\n", stats[s_maximum]);
      fprintf(stdout, "mean_nedge:                     %.11g\n", stats[s_mean]);
      fprintf(stdout, "stddev_nedge:                   %.11g\n", stats[s_std]);
      double* secs_per_edge = (double*)xmalloc(num_bfs_roots * sizeof(double));
      for (i = 0; i < num_bfs_roots; ++i) secs_per_edge[i] = bfs_times[i] / edge_counts[i];
      get_statistics(secs_per_edge, num_bfs_roots, stats);
      fprintf(stdout, "min_TEPS:                       %g\n", 1. / stats[s_maximum]);
      fprintf(stdout, "firstquartile_TEPS:             %g\n", 1. / stats[s_thirdquartile]);
      fprintf(stdout, "median_TEPS:                    %g\n", 1. / stats[s_median]);
      fprintf(stdout, "thirdquartile_TEPS:             %g\n", 1. / stats[s_firstquartile]);
      fprintf(stdout, "max_TEPS:                       %g\n", 1. / stats[s_minimum]);
      fprintf(stdout, "harmonic_mean_TEPS:             %g\n", 1. / stats[s_mean]);
      /* Formula from:
       * Title: The Standard Errors of the Geometric and Harmonic Means and
       *        Their Application to Index Numbers
       * Author(s): Nilan Norris
       * Source: The Annals of Mathematical Statistics, Vol. 11, No. 4 (Dec., 1940), pp. 445-448
       * Publisher(s): Institute of Mathematical Statistics
       * Stable URL: http://www.jstor.org/stable/2235723
       * (same source as in specification). */
      fprintf(stdout, "harmonic_stddev_TEPS:           %g\n", stats[s_std] / (stats[s_mean] * stats[s_mean] * sqrt(num_bfs_roots - 1)));
      free(secs_per_edge); secs_per_edge = NULL;
      free(edge_counts); edge_counts = NULL;
      get_statistics(validate_times, num_bfs_roots, stats);
      fprintf(stdout, "min_validate:                   %g\n", stats[s_minimum]);
      fprintf(stdout, "firstquartile_validate:         %g\n", stats[s_firstquartile]);
      fprintf(stdout, "median_validate:                %g\n", stats[s_median]);
      fprintf(stdout, "thirdquartile_validate:         %g\n", stats[s_thirdquartile]);
      fprintf(stdout, "max_validate:                   %g\n", stats[s_maximum]);
      fprintf(stdout, "mean_validate:                  %g\n", stats[s_mean]);
      fprintf(stdout, "stddev_validate:                %g\n", stats[s_std]);
#if 0
      for (i = 0; i < num_bfs_roots; ++i) {
        fprintf(stdout, "Run %3d:                        %g s, validation %g s\n", i + 1, bfs_times[i], validate_times[i]);
      }
#endif
    }
  }
  free(bfs_times);
  free(validate_times);

  cleanup_globals();
  MPI_Finalize();
  return 0;
}
Exemple #18
0
static int test_mpio_derived_dtype(char *filename) {

    MPI_File fh;
    char mpi_err_str[MPI_MAX_ERROR_STRING];
    int  mpi_err_strlen;
    int  mpi_err;
    int  i;
    int  nerrors = 0;		/* number of errors */
    MPI_Datatype  etype,filetype;
    MPI_Datatype  adv_filetype,bas_filetype[2];
    MPI_Datatype  etypenew, filetypenew;
    MPI_Offset    disp;
    MPI_Status    Status;
    MPI_Aint      adv_disp[2];
    MPI_Aint      offsets[1];
    int           blocklens[1],adv_blocklens[2];
    int           count,outcount;
    int           retcode;

    int mpi_rank,mpi_size;

    char          buf[3],outbuf[3] = {0};

    MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
    retcode = 0;
    for(i=0;i<3;i++)
      buf[i] = i+1;


    if ((mpi_err = MPI_File_open(MPI_COMM_WORLD, filename,
				 MPI_MODE_RDWR | MPI_MODE_CREATE,
				 MPI_INFO_NULL, &fh))
	    != MPI_SUCCESS){
	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_open failed (%s)\n", mpi_err_str);
	return 1;
    }

    disp  = 0;
    etype = MPI_BYTE;

    count = 1;
    blocklens[0] = 1;
    offsets[0]   = 0;

    if((mpi_err= MPI_Type_hindexed(count,blocklens,offsets,MPI_BYTE,&filetype))
       != MPI_SUCCESS){
      	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_contiguous failed (%s)\n", mpi_err_str);
	return 1;
    }

    if((mpi_err=MPI_Type_commit(&filetype))!=MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
	return 1;
    }

    count = 1;
    blocklens[0]=1;
    offsets[0] = 1;
    if((mpi_err= MPI_Type_hindexed(count,blocklens,offsets,MPI_BYTE,&filetypenew))
       != MPI_SUCCESS){
      	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_contiguous failed (%s)\n", mpi_err_str);
	return 1;
    }

    if((mpi_err=MPI_Type_commit(&filetypenew))!=MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
	return 1;
    }

    outcount         = 2;
    adv_blocklens[0] = 1;
    adv_blocklens[1] = 1;
    adv_disp[0]      = 0;
    adv_disp[1]      = 1;
    bas_filetype[0]  = filetype;
    bas_filetype[1]  = filetypenew;

    if((mpi_err= MPI_Type_struct(outcount,adv_blocklens,adv_disp,bas_filetype,&adv_filetype))
       != MPI_SUCCESS){
      	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_struct failed (%s)\n", mpi_err_str);
	return 1;
    }
    if((mpi_err=MPI_Type_commit(&adv_filetype))!=MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
	return 1;
    }


    if((mpi_err = MPI_File_set_view(fh,disp,etype,adv_filetype,"native",MPI_INFO_NULL))!= MPI_SUCCESS){
      MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_set_view failed (%s)\n", mpi_err_str);
	return 1;
    }

    if((mpi_err = MPI_File_write(fh,buf,3,MPI_BYTE,&Status))!= MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_write failed (%s)\n", mpi_err_str);
	return 1;
      ;
    }


    if((mpi_err = MPI_File_close(&fh)) != MPI_SUCCESS){
       MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_close failed (%s)\n", mpi_err_str);
	return 1;
    }


    if((mpi_err = MPI_File_open(MPI_COMM_WORLD,filename,MPI_MODE_RDONLY,MPI_INFO_NULL,&fh)) != MPI_SUCCESS){
       MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_open failed (%s)\n", mpi_err_str);
	return 1;
    }

    if((mpi_err = MPI_File_set_view(fh,0,MPI_BYTE,MPI_BYTE,"native",MPI_INFO_NULL))!= MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_set_view failed (%s)\n", mpi_err_str);
	return 1;
    }
    if((mpi_err = MPI_File_read(fh,outbuf,3,MPI_BYTE,&Status))!=MPI_SUCCESS){
      MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
      printf("MPI_File_read failed (%s)\n", mpi_err_str);
      return 1;
    }

    if(outbuf[2]==2) {
       retcode = 0;
    }
    else {
/*      if(mpi_rank == 0) {
       printf("complicated derived datatype is NOT working at this platform\n");
       printf("go back to hdf5/config and find the corresponding\n");
       printf("configure-specific file and change ?????\n");
      }
*/
       retcode = -1;
   }

    if((mpi_err = MPI_File_close(&fh)) != MPI_SUCCESS){
       MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_close failed (%s)\n", mpi_err_str);
	return 1;
    }


    mpi_err = MPI_Barrier(MPI_COMM_WORLD);
#ifdef H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS
    if(retcode == -1) {
	if(mpi_rank == 0) {
	    printf("Complicated derived datatype is NOT working at this platform\n");
	    printf("Go back to hdf5/config and find the corresponding\n");
	    printf("configure-specific file (for example, powerpc-ibm-aix5.x) and add\n");
	    printf("hdf5_cv_mpi_complex_derived_datatype_works=${hdf5_cv_mpi_complex_derived_datatype-works='no'}\n");
	    printf(" at the end of the file.\n");
	    printf(" Please report to [email protected] about this problem.\n");
	}
	retcode = 1;
    }
#else
    if(retcode == 0) {
	if(mpi_rank == 0) {
	    printf(" This is NOT an error, What it really says is\n");
	    printf("Complicated derived datatype is WORKING at this platform\n");
	    printf(" Go back to hdf5/config and find the corresponding \n");
	    printf(" configure-specific file (for example, powerpc-ibm-aix5.x) and delete the line\n");
	    printf("hdf5_cv_mpi_complex_derived_datatype_works=${hdf5_cv_mpi_complex_derived_datatype-works='no'}\n");
	    printf(" at the end of the file.\n");
	    printf("Please report to [email protected] about this problem.\n");
	}
	retcode = 1;
    }
    if(retcode == -1) retcode = 0;
#endif
    return retcode;
}
int
main (int argc, char **argv)
{
  MPI_Request request;
  MPI_File fh;
  MPI_Datatype ftype;
  MPI_Offset offset;
  MPI_Status status;
  int rank, wsize, fsize, i;
  char file_name[128];
  int buf[BUF_SIZE * TEST_OPS];
  int count;

  MPI_Init (&argc, &argv);

  MPI_Comm_size (MPI_COMM_WORLD, &wsize);
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);

  strcpy (file_name, argv[0]);
  strcat (file_name, ".tmp");

  MPI_File_open (MPI_COMM_WORLD, file_name, MPI_MODE_RDWR | MPI_MODE_CREATE,
		 MPI_INFO_NULL, &fh);

  fsize = wsize * BUF_SIZE * TEST_OPS;
  MPI_File_preallocate (fh, fsize);

  memset (buf, 0, BUF_SIZE * TEST_OPS);
  offset = 0;
  count = BLOCK_SIZE;

  for (i = 0; i < TEST_OPS; i++)
    {
      offset = i * BLOCK_SIZE + (rank * BLOCK_SIZE * TEST_OPS);

      MPI_File_seek (fh, offset, MPI_SEEK_SET);
      MPI_File_write (fh, buf, count, MPI_INT, &status);

      MPI_File_seek (fh, offset, MPI_SEEK_SET);
      MPI_File_read (fh, buf, count, MPI_INT, &status);
    }

  for (i = 0; i < TEST_OPS; i++)
    {
      offset = i * BLOCK_SIZE + (rank * BLOCK_SIZE * TEST_OPS);
      MPI_File_write_at (fh, offset, buf, count, MPI_INT, &status);
      MPI_File_read_at (fh, offset, buf, count, MPI_INT, &status);
    }

  MPI_Type_vector (fsize / BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE * wsize,
		   MPI_INT, &ftype);
  MPI_Type_commit (&ftype);

  offset = rank * BLOCK_SIZE * TEST_OPS;
  count = BLOCK_SIZE * TEST_OPS;

  MPI_File_set_view (fh, offset, MPI_INT, ftype, "native", MPI_INFO_NULL);
  MPI_File_write_all (fh, buf, count, MPI_INT, &status);
  MPI_File_read_all (fh, buf, count, MPI_INT, &status);

  MPI_File_close (&fh);

  MPI_Finalize ();
}
Exemple #20
0
static int
test_mpio_special_collective(char *filename)
{
    int  mpi_size, mpi_rank;
    MPI_File fh;
    MPI_Datatype etype,buftype,filetype;
    char mpi_err_str[MPI_MAX_ERROR_STRING];
    int  mpi_err_strlen;
    int  mpi_err;
    char writedata[2];
    char *buf;
    int  i;
    int  count,bufcount;
    int blocklens[2];
    MPI_Aint offsets[2];
    MPI_Offset  mpi_off;
    MPI_Status  mpi_stat;
    int  retcode;

    MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
    retcode = 0;

    /* create MPI data type */
    etype = MPI_BYTE;
    if(mpi_rank == 0 || mpi_rank == 1) {
        count = DIMSIZE;
        bufcount = 1;
    }
    else {
        count = 0;
        bufcount = 0;
    }

    blocklens[0] = count;
    offsets[0] = mpi_rank*count;
    blocklens[1] = count;
    offsets[1] = (mpi_size+mpi_rank)*count;

    if(count !=0) {
      if((mpi_err= MPI_Type_hindexed(2,blocklens,offsets,etype,&filetype))
       != MPI_SUCCESS){
      	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_contiguous failed (%s)\n", mpi_err_str);
	return 1;
      }

      if((mpi_err=MPI_Type_commit(&filetype))!=MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
	return 1;
      }


      if((mpi_err= MPI_Type_hindexed(2,blocklens,offsets,etype,&buftype))
       != MPI_SUCCESS){
      	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_contiguous failed (%s)\n", mpi_err_str);
	return 1;
      }

      if((mpi_err=MPI_Type_commit(&buftype))!=MPI_SUCCESS){
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
	return 1;
      }
     }
     else {

       filetype = MPI_BYTE;
       buftype  = MPI_BYTE;
     }

   /* Open a file */
    if ((mpi_err = MPI_File_open(MPI_COMM_WORLD, filename,
	    MPI_MODE_RDWR | MPI_MODE_CREATE ,
	    MPI_INFO_NULL, &fh))
	    != MPI_SUCCESS){
	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_open failed (%s)\n", mpi_err_str);
	return 1;
    }

    /* each process writes some data */
    for (i=0; i < 2*DIMSIZE; i++)
	writedata[i] = mpi_rank*DIMSIZE + i;


     mpi_off = 0;
    if((mpi_err = MPI_File_set_view(fh, mpi_off, MPI_BYTE, filetype, "native", MPI_INFO_NULL))
        != MPI_SUCCESS) {
	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_set_view failed (%s)\n", mpi_err_str);
	return 1;
    }

    buf   = writedata;
    if ((mpi_err = MPI_File_write_at_all(fh, mpi_off, buf, bufcount, buftype,
	    &mpi_stat))
	    != MPI_SUCCESS){
	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_write_at offset(%ld), bytes (%d), failed (%s)\n",
		(long) mpi_off, bufcount, mpi_err_str);
	return 1;
    };

     if ((mpi_err = MPI_File_close(&fh))
	    != MPI_SUCCESS){
	MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
	printf("MPI_File_close failed. \n");
	return 1;
    };

    mpi_err = MPI_Barrier(MPI_COMM_WORLD);
#ifdef H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS
    if(retcode != 0) {
	if(mpi_rank == 0) {
	    printf("special collective IO is NOT working at this platform\n");
	    printf("Go back to hdf5/config and find the corresponding\n");
	    printf("configure-specific file (for example, powerpc-ibm-aix5.x) and add\n");
	    printf("hdf5_cv_mpi_special_collective_io_works=${hdf5_cv_mpi_special_collective_io_works='no'}\n");
	    printf(" at the end of the file.\n");
	    printf(" Please report to [email protected] about this problem.\n");
	}
	retcode = 1;
    }
#else
    if(retcode == 0) {
	if(mpi_rank == 0) {
	    printf(" This is NOT an error, What it really says is\n");
	    printf("special collective IO is WORKING at this platform\n");
	    printf(" Go back to hdf5/config and find the corresponding \n");
	    printf(" configure-specific file (for example, powerpc-ibm-aix5.x) and delete the line\n");
	    printf("hdf5_cv_mpi_special_collective_io_works=${hdf5_cv_mpi_special_collective_io_works='no'}\n");
	    printf(" at the end of the file.\n");
	    printf("Please report to [email protected] about this problem.\n");
	}
	retcode = 1;
    }
#endif
    return retcode;
}
Exemple #21
0
int main(int argc, char **argv)
{
    int *buf, i, mynod, nprocs, len, b[3];
    int errs = 0, toterrs;
    MPI_Aint d[3];
    MPI_File fh;
    MPI_Status status;
    char *filename;
    MPI_Datatype typevec, newtype, t[3];

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &mynod);

    if (nprocs != 2) {
        fprintf(stderr, "Run this program on two processes\n");
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

/* process 0 takes the file name as a command-line argument and
   broadcasts it to other processes */
    if (!mynod) {
        i = 1;
        while ((i < argc) && strcmp("-fname", *argv)) {
            i++;
            argv++;
        }
        if (i >= argc) {
            fprintf(stderr, "\n*#  Usage: noncontig_coll -fname filename\n\n");
            MPI_Abort(MPI_COMM_WORLD, 1);
        }
        argv++;
        len = strlen(*argv);
        filename = (char *) malloc(len + 1);
        strcpy(filename, *argv);
        MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
        MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD);
    } else {
        MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD);
        filename = (char *) malloc(len + 1);
        MPI_Bcast(filename, len + 1, MPI_CHAR, 0, MPI_COMM_WORLD);
    }

    buf = (int *) malloc(SIZE * sizeof(int));

    MPI_Type_vector(SIZE / 2, 1, 2, MPI_INT, &typevec);

    b[0] = b[1] = b[2] = 1;
    d[0] = 0;
    d[1] = mynod * sizeof(int);
    d[2] = SIZE * sizeof(int);
    t[0] = MPI_LB;
    t[1] = typevec;
    t[2] = MPI_UB;

    MPI_Type_struct(3, b, d, t, &newtype);
    MPI_Type_commit(&newtype);
    MPI_Type_free(&typevec);

    if (!mynod) {
#if VERBOSE
        fprintf(stderr,
                "\ntesting noncontiguous in memory, noncontiguous in file using collective I/O\n");
#endif
        MPI_File_delete(filename, MPI_INFO_NULL);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    MPI_CHECK(MPI_File_open(MPI_COMM_WORLD, filename,
                            MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh));

    MPI_CHECK(MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", MPI_INFO_NULL));

    for (i = 0; i < SIZE; i++)
        buf[i] = i + mynod * SIZE;
    MPI_CHECK(MPI_File_write_all(fh, buf, 1, newtype, &status));

    MPI_Barrier(MPI_COMM_WORLD);

    for (i = 0; i < SIZE; i++)
        buf[i] = -1;

    MPI_CHECK(MPI_File_read_at_all(fh, 0, buf, 1, newtype, &status));

    for (i = 0; i < SIZE; i++) {
        if (!mynod) {
            if ((i % 2) && (buf[i] != -1)) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]);
            }
            if (!(i % 2) && (buf[i] != i)) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], i);
            }
        } else {
            if ((i % 2) && (buf[i] != i + mynod * SIZE)) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
                        mynod, i, buf[i], i + mynod * SIZE);
            }
            if (!(i % 2) && (buf[i] != -1)) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]);
            }
        }
    }

    MPI_CHECK(MPI_File_close(&fh));

    MPI_Barrier(MPI_COMM_WORLD);

    if (!mynod) {
#if VERBOSE
        fprintf(stderr,
                "\ntesting noncontiguous in memory, contiguous in file using collective I/O\n");
#endif
        MPI_File_delete(filename, MPI_INFO_NULL);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    MPI_CHECK(MPI_File_open(MPI_COMM_WORLD, filename,
                            MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh));

    for (i = 0; i < SIZE; i++)
        buf[i] = i + mynod * SIZE;
    MPI_CHECK(MPI_File_write_at_all(fh, mynod * (SIZE / 2) * sizeof(int),
                                    buf, 1, newtype, &status));

    MPI_Barrier(MPI_COMM_WORLD);

    for (i = 0; i < SIZE; i++)
        buf[i] = -1;

    MPI_CHECK(MPI_File_read_at_all(fh, mynod * (SIZE / 2) * sizeof(int), buf, 1, newtype, &status));

    for (i = 0; i < SIZE; i++) {
        if (!mynod) {
            if ((i % 2) && (buf[i] != -1)) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]);
            }
            if (!(i % 2) && (buf[i] != i)) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], i);
            }
        } else {
            if ((i % 2) && (buf[i] != i + mynod * SIZE)) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
                        mynod, i, buf[i], i + mynod * SIZE);
            }
            if (!(i % 2) && (buf[i] != -1)) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]);
            }
        }
    }

    MPI_CHECK(MPI_File_close(&fh));

    MPI_Barrier(MPI_COMM_WORLD);

    if (!mynod) {
#if VERBOSE
        fprintf(stderr,
                "\ntesting contiguous in memory, noncontiguous in file using collective I/O\n");
#endif
        MPI_File_delete(filename, MPI_INFO_NULL);
    }
    MPI_Barrier(MPI_COMM_WORLD);

    MPI_CHECK(MPI_File_open(MPI_COMM_WORLD, filename,
                            MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh));

    MPI_CHECK(MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", MPI_INFO_NULL));

    for (i = 0; i < SIZE; i++)
        buf[i] = i + mynod * SIZE;
    MPI_CHECK(MPI_File_write_all(fh, buf, SIZE, MPI_INT, &status));

    MPI_Barrier(MPI_COMM_WORLD);

    for (i = 0; i < SIZE; i++)
        buf[i] = -1;

    MPI_CHECK(MPI_File_read_at_all(fh, 0, buf, SIZE, MPI_INT, &status));

    for (i = 0; i < SIZE; i++) {
        if (!mynod) {
            if (buf[i] != i) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], i);
            }
        } else {
            if (buf[i] != i + mynod * SIZE) {
                errs++;
                fprintf(stderr, "Process %d: buf %d is %d, should be %d\n",
                        mynod, i, buf[i], i + mynod * SIZE);
            }
        }
    }

    MPI_CHECK(MPI_File_close(&fh));

    MPI_Allreduce(&errs, &toterrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
    if (mynod == 0) {
        if (toterrs > 0) {
            fprintf(stderr, "Found %d errors\n", toterrs);
        } else {
            fprintf(stdout, " No Errors\n");
        }
    }

    MPI_Type_free(&newtype);
    free(buf);
    free(filename);
    MPI_Finalize();
    return 0;
}
Exemple #22
0
/**
 * \brief Measures the time to write once to a file.
 *
 * Only one process is active. It writes once to a file.
 *
 * Remark:<br>
 * With the <tt>O_DIRECT</tt> flag set, cache effects are minimized, because I/O
 * is done directly to/from user space buffers. The operation system's page
 * cache is bypassed. Under Linux 2.6 alignment to 512-byte boundaries is
 * required for buffer and file offset. Thus the following parameters should be
 * set in a SKaMPI input file:
 * - <tt>set_send_buffert_alignment (512)</tt>
 * - <tt>set_recv_buffert_alignment (512)</tt>
 * - <tt>switch_buffer_cycling_off ()</tt><br>
 *
 * <tt>O_DIRECT</tt> is only relevant if the POSIX-API is used for I/O.
 * 
 * For more information please refer to the <tt>open ()</tt> man pages.
 *
 * \param[in] size        size of memory buffer, i.e. number of <tt>MPI_BYTE</tt>s
 * \param[in] api         POSIX-API or MPI-API for I/O accesses
 * \param[in] create_flag write into existing file (FALSE) or create it (TRUE)
 * \param[in] directio_flag open file with <tt>O_DIRECT</tt> flag to minimize
 *                          cache effects
 *
 * \return    measured time 
 */
double measure_MPI_IO_write_file_once (int size, char *api, int create_flag, int directio_flag){
  double     start_time = 1.0, end_time = 0.0;
  int        open_flags;
  char       *error_string;
  
  if (get_measurement_rank () == 0){
    if (strcmp (api, POSIX_API) == 0){

      if (directio_flag != 0)
	open_flags = O_WRONLY | O_DIRECT;
      else
	open_flags = O_WRONLY;

      errno = 0;

      if (create_flag == 0){	/* open existing file */

	if ((io_fd = open (io_filename, open_flags)) < 0){
	  error_string = strerror (errno);
	  error_with_abort (errno,
			    "\nmeasure_MPI_IO_write_file_once (int %d, char * %s, int %d, int %d) failed."
			    "\nCannot open local file (write only mode)."
			    "\nError: %s\n",
			    size, api, create_flag, directio_flag, error_string);
	}
      }
      else {			/* open nonexisting file and create it */
	
	if ((io_fd = open (io_filename, open_flags|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0){
	  error_string = strerror (errno);
	  error_with_abort (errno,
			   "\nmeasure_MPI_IO_write_file_once (int %d, char * %s, int %d, int %d) failed."
			   "\nCannot open local file (write only mode)."
			   "\nError: %s\n",
			    size, api, create_flag, directio_flag, error_string);
	}
      }

      start_time = start_synchronization ();
      write (io_fd, get_send_buffer (), size);
      fsync (io_fd);
      end_time = MPI_Wtime ();

      close (io_fd);

    }
    else{ 			/* if strcmp (api, POSIX_API) != 0 */

      if (create_flag == 0){

	MPI_File_open (MPI_COMM_SELF, io_filename, MPI_MODE_WRONLY, MPI_INFO_NULL, &io_fh);
      }
      else{ 			/* if create_flag != 0*/

	MPI_File_open (MPI_COMM_SELF, io_filename, MPI_MODE_WRONLY|MPI_MODE_CREATE, MPI_INFO_NULL, &io_fh);
      }
      
      MPI_File_set_view (io_fh, (MPI_Offset)0, 
			MPI_BYTE, MPI_BYTE,
			"native", MPI_INFO_NULL);

      start_time = start_synchronization ();
      MPI_File_write (io_fh, get_send_buffer (), size, MPI_BYTE, MPI_STATUS_IGNORE);
      MPI_File_sync (io_fh);
      end_time = MPI_Wtime ();
      
      MPI_File_close (&io_fh);
    }
  }
  else if (get_measurement_rank () != 0) {
    start_synchronization ();
  }
  stop_synchronization ();

  if (get_measurement_rank () == 0)
    return end_time - start_time;
  else
    return -1.0;
}
Exemple #23
0
static int
test_mpio_special_collective(char *filename)
{
    int  mpi_size, mpi_rank;
    MPI_File fh;
    MPI_Datatype etype,buftype,filetype;
    char mpi_err_str[MPI_MAX_ERROR_STRING];
    int  mpi_err_strlen;
    int  mpi_err;
    char writedata[2*DIMSIZE];
    char filerep[7] = "native";
    int  i;
    int  count,bufcount;
    int blocklens[2];
    MPI_Aint offsets[2];
    MPI_Offset  mpi_off = 0;
    MPI_Status  mpi_stat;
    int  retcode = 0;

    MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);

    /* create MPI data type */
    etype = MPI_BYTE;
    if(mpi_rank == 0 || mpi_rank == 1) {
        count = DIMSIZE;
        bufcount = 1;
    } /* end if */
    else {
        count = 0;
        bufcount = 0;
    } /* end else */

    blocklens[0] = count;
    offsets[0] = mpi_rank*count;
    blocklens[1] = count;
    offsets[1] = (mpi_size+mpi_rank)*count;

    if(count !=0) {
        if((mpi_err = MPI_Type_hindexed(2,
                                        blocklens,
                                        offsets,
                                        etype,
                                        &filetype)) != MPI_SUCCESS) {
            MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
            printf("MPI_Type_contiguous failed (%s)\n", mpi_err_str);
            return 1;
        } /* end if */

        if((mpi_err = MPI_Type_commit(&filetype)) != MPI_SUCCESS) {
            MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
            printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
            return 1;
        } /* end if */

        if((mpi_err = MPI_Type_hindexed(2,
                                        blocklens,
                                        offsets,
                                        etype,
                                        &buftype)) != MPI_SUCCESS) {
            MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
            printf("MPI_Type_contiguous failed (%s)\n", mpi_err_str);
            return 1;
        } /* end if */

        if((mpi_err = MPI_Type_commit(&buftype)) != MPI_SUCCESS) {
            MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
            printf("MPI_Type_commit failed (%s)\n", mpi_err_str);
            return 1;
        } /* end if */
    } /* end if */
    else {
        filetype = MPI_BYTE;
        buftype  = MPI_BYTE;
    } /* end else */

    /* Open a file */
    if ((mpi_err = MPI_File_open(MPI_COMM_WORLD,
                                 filename,
                                 MPI_MODE_RDWR | MPI_MODE_CREATE,
                                 MPI_INFO_NULL,
                                 &fh)) != MPI_SUCCESS) {
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
        printf("MPI_File_open failed (%s)\n", mpi_err_str);
        return 1;
    } /* end if */

    /* each process writes some data */
    for (i=0; i < 2*DIMSIZE; i++)
        writedata[i] = (char)(mpi_rank*DIMSIZE + i);

    /* Set the file view */
    if((mpi_err = MPI_File_set_view(fh,
                                    mpi_off,
                                    MPI_BYTE,
                                    filetype,
                                    filerep,
                                    MPI_INFO_NULL)) != MPI_SUCCESS) {
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
        printf("MPI_File_set_view failed (%s)\n", mpi_err_str);
        return 1;
    } /* end if */

    /* Collectively write into the file */
    if ((mpi_err = MPI_File_write_at_all(fh,
                                         mpi_off,
                                         writedata,
                                         bufcount,
                                         buftype,
                                         &mpi_stat)) != MPI_SUCCESS) {
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
        printf("MPI_File_write_at offset(%ld), bytes (%d), failed (%s)\n",
               (long) mpi_off, bufcount, mpi_err_str);
        return 1;
    } /* end if */

    /* Close the file */
    if ((mpi_err = MPI_File_close(&fh)) != MPI_SUCCESS) {
        MPI_Error_string(mpi_err, mpi_err_str, &mpi_err_strlen);
        printf("MPI_File_close failed. \n");
        return 1;
    } /* end if */

    /* Perform a barrier */
    mpi_err = MPI_Barrier(MPI_COMM_WORLD);
    if(retcode != 0) {
        if(mpi_rank == 0) {
            printf("special collective IO is NOT working at this platform\n");
            printf(" Please report to [email protected] about this problem.\n");
        } /* end if */
        retcode = 1;
    } /* end if */

    return retcode;

} /* test_mpio_special_collective */
Exemple #24
0
int main(int argc, char *argv[])
{
	int iarrayOfSizes[2], iarrayOfSubsizes[2], iarrayOfStarts[2], ilocal_size;
	int nproc[2], periods[2], icoord[2];
	int m, n, i, j, wsize, wrank, crank, ndims, lrows, lcols, grow, gcol, err;
	MPI_Datatype filetype;
	MPI_File     fh;
	MPI_Comm     cartcomm;
	MPI_Info     info0, info3;
	double       t, topen, twrite, tclose, wrate;
	double       *local_array;
	char         nstripesStr[12], stripeUnitStr[12];
	int          nstripes = -1;
	int          stripeUnit = -1;
	MPI_Offset   headerSize = 0;

	MPI_Init(0,0);

	MPI_Comm_rank(MPI_COMM_WORLD, &wrank);

	/* Get global array size */
	m = n = 128;      /* Set default size */

	/* ioda [ n ] [ m ] [ nstripes ] [ stripeunit ] [ headersize ] */
	if (argc > 0) {
		if (argc > 1) m = atoi(argv[1]);
		if (argc > 2) n = atoi(argv[2]);
		if (argc > 3) nstripes = atoi(argv[3]);
		if (argc > 4) stripeUnit = atoi(argv[4]);
	        if (argc > 5) headerSize = atoi(argv[5]);
		if (argc > 6) {
			if (wrank == 0)
				fprintf(stderr,"Unrecognized argument %s\n", argv[6]);
			MPI_Abort(MPI_COMM_WORLD,1);
		}
	}
	if (wrank == 0) printf("Matrix is [%d,%d]; file dir = %s\n", m, n, MYSCRATCHDIR );

	/* The default number of stripes = totalsize/1M */
	if (nstripes < 0) {
		nstripes = n * m * sizeof(double) / (1024*1024);
		if (nstripes < 1) nstripes = 1;
	}
	if (wrank == 0) printf("nstripes = %d, stripeUnit = %d, header size = %d\n",
			       nstripes, stripeUnit, (int)headerSize);

	/* Use topology routines to get decomposition and coordinates */
	MPI_Comm_size(MPI_COMM_WORLD, &wsize);
	nproc[0] = 0; nproc[1] = 0;
	ndims = 2;
	MPI_Dims_create(wsize, ndims, nproc);
	periods[0] = 0; periods[1] = 0;
	MPI_Cart_create(MPI_COMM_WORLD, ndims, nproc, periods, 1, &cartcomm);
	MPI_Comm_rank(cartcomm, &crank);
	MPI_Cart_coords(cartcomm, crank, ndims, icoord);

	iarrayOfSizes[0]    = m;
	iarrayOfSizes[1]    = n;
	iarrayOfSubsizes[0] = m/nproc[0];
	iarrayOfSubsizes[1] = n/nproc[1];
	iarrayOfStarts[0]   = icoord[0] * iarrayOfSubsizes[0];
	iarrayOfStarts[1]   = icoord[1] * iarrayOfSubsizes[1];

	/* Initialize my block of the data */
	ilocal_size = iarrayOfSubsizes[0] * iarrayOfSubsizes[1];
	lrows = iarrayOfSubsizes[0];
	lcols = iarrayOfSubsizes[1];
	local_array = (double *)malloc(lrows*lcols*sizeof(double));
	gcol  = iarrayOfStarts[1];
	grow = iarrayOfStarts[0];
	for (i=0; i<lrows; i++) {
		for (j=0; j<lcols; j++) {
			local_array[j*lrows+i] = (grow+i) + (gcol+j)*m;
		}
	}

	/* Fortran order simply means the data is stored by columns */
	MPI_Type_create_subarray(ndims, iarrayOfSizes, iarrayOfSubsizes,
				 iarrayOfStarts, MPI_ORDER_FORTRAN, MPI_DOUBLE,
				 &filetype);
	MPI_Type_commit(&filetype);

	info0 = MPI_INFO_NULL;
	info3 = MPI_INFO_NULL;
	if (nstripes > 0 || stripeUnit > 0) {
		MPI_Info_create(&info0);
		if (nstripes > 0) {
			snprintf(nstripesStr, sizeof(nstripesStr), "%d", nstripes);
			MPI_Info_set(info0, "striping_factor", nstripesStr);
			MPI_Info_set(info0, "cb_nodes", nstripesStr);
		}
		if (stripeUnit > 0) {
			snprintf(stripeUnitStr, sizeof(stripeUnitStr), "%d", stripeUnit);
			MPI_Info_set(info0, "striping_unit", stripeUnitStr);
		}
		MPI_Info_dup(info0, &info3);
		MPI_Info_set(info3, "romio_no_indep_rw", "true");

		/* Other hints to consider:
		      direct_io=true

		         The default cb_buffer_size is 16777216 , but is overridden by the
			    striping unit, which is smaller by default.
		*/
	}

	/* level - 3 */
	MPI_Barrier(MPI_COMM_WORLD);
	t = MPI_Wtime();
	err = MPI_File_open(cartcomm, MYSCRATCHDIR "testfile-3.out",
			    MPI_MODE_CREATE | MPI_MODE_RDWR, info3, &fh);
	topen = MPI_Wtime() - t;
	if (err != MPI_SUCCESS) myAbort(err, "open testfile-3.out");

	if (headerSize > 0) {
	        /* Simulate writing a header */
	        if (wrank == 0) {
			char *header;
			header = (char *)calloc(1,(size_t)headerSize);
			MPI_File_write(fh, header, headerSize, MPI_BYTE, MPI_STATUS_IGNORE);
			free(header);
		}
	        MPI_Barrier(cartcomm);
	}

	MPI_File_set_view(fh, headerSize, MPI_DOUBLE, filetype, "native", MPI_INFO_NULL);

	MPI_Barrier(MPI_COMM_WORLD);
	t = MPI_Wtime();
	err = MPI_File_write_all(fh, local_array, ilocal_size, MPI_DOUBLE,
				 MPI_STATUS_IGNORE);
	twrite = MPI_Wtime() - t;
	if (err != MPI_SUCCESS) myAbort(err, "collective write");

	err = MPI_File_close(&fh);
	tclose = MPI_Wtime() - t;
	/* tclose is the time for the write(s) + the close, in case the
	   implementation delays (some of) the writes until the close */
	if (err != MPI_SUCCESS) myAbort(err, "close testfile-3.out");

	MPI_Allreduce(MPI_IN_PLACE, &topen, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
	MPI_Allreduce(MPI_IN_PLACE, &twrite, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
	MPI_Allreduce(MPI_IN_PLACE, &tclose, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
	if (twrite > 0)
		wrate = (double)m * (double)n * sizeof(double)/twrite;
	if (wrank == 0)
		printf("%d\t[%d,%d]\t%d\t%.2e\t%.2e\t%.2e\t%.2e\n", wsize, m, n, nstripes, topen,
		       twrite, tclose, wrate);

	/* level - 0 */
	MPI_Barrier(MPI_COMM_WORLD);
	t = MPI_Wtime();
	err = MPI_File_open(cartcomm, MYSCRATCHDIR "testfile-0.out",
			    MPI_MODE_CREATE | MPI_MODE_RDWR, info0, &fh);
	topen = MPI_Wtime() - t;
	if (err != MPI_SUCCESS) myAbort(err, "open testfile-0.out");

	if (headerSize > 0) {
	        /* Simulate writing a header */
	        if (wrank == 0) {
			char *header;
			header = (char *)calloc(1,(size_t)headerSize);
			MPI_File_write(fh, header, headerSize, MPI_BYTE, MPI_STATUS_IGNORE);
			free(header);
		}
	        MPI_Barrier(cartcomm);
	}

	MPI_Barrier(MPI_COMM_WORLD);
	t = MPI_Wtime();
	gcol = iarrayOfStarts[1];
	grow = iarrayOfStarts[0];
	for (j=0; j<lcols; j++) {
	MPI_Offset offset = headerSize +
		((MPI_Offset)(grow) + (MPI_Offset)(gcol+j)*m) * sizeof(double);
	err = MPI_File_write_at(fh, offset, local_array+j*lrows, lrows, MPI_DOUBLE,
				MPI_STATUS_IGNORE);
	if (err != MPI_SUCCESS) myAbort(err, "write at");
	}
	twrite = MPI_Wtime() - t;

	err = MPI_File_close(&fh);
	tclose = MPI_Wtime() - t;
	/* tclose is the time for the write(s) + the close, in case the
	   implementation delays (some of) the writes until the close */
	if (err != MPI_SUCCESS) myAbort(err, "close testfile-0");

	MPI_Allreduce(MPI_IN_PLACE, &topen, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
	MPI_Allreduce(MPI_IN_PLACE, &twrite, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
	MPI_Allreduce(MPI_IN_PLACE, &tclose, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
	if (twrite > 0)
		wrate = (double)m * (double)n * sizeof(double)/twrite;
	if (wrank == 0)
		printf("%d\t[%d,%d]\t%d\t%.2e\t%.2e\t%.2e\t%.2e\n", wsize, m, n, nstripes, topen,
		       twrite, tclose, wrate);

	if (info0 != MPI_INFO_NULL) {
		MPI_Info_free(&info0);
		MPI_Info_free(&info3);
	}
	free(local_array);
	MPI_Finalize();
	return 0;
}