예제 #1
0
//----------------------------------------------------------------
// Return a negative value when failed, otherwise return 0
int read_var_from_netcdf(int file_id, const char *var_name, struct Type type)
{
  int TIMES=1;
  int LATS=local_box_size[1];
  int LONS=local_box_size[0];
  assert(var_name != 0);
  assert(var_data != 0);
  int varidp,ndims,nvars,ngatts,unlimited;
  nc_type xtypep;
//int dataset_id = H5Dopen2(file_id, var_name, H5P_DEFAULT);
 
  int dataset_id = ncmpi_inq_varid(file_id, var_name, &varidp);
  MPI_Offset start[]={local_box_offset[2],local_box_offset[1],local_box_offset[0]};
  MPI_Offset count[]={TIMES,LATS,LONS};

  dataset_id = ncmpi_inq_vartype(file_id,varidp, &xtypep);


//  if (dataset_id !=0)
//    terminate_with_error_msg("ERROR: Failed to open NetCDF dataset for variable %s\n", var_name);

  int read_error = 0;

  if (type.atomic_type == DOUBLE)
    
    read_error = ncmpi_get_vara_double(file_id, varidp, start, count, var_data);
  else if (type.atomic_type == FLOAT){

    ncmpi_begin_indep_data(file_id);
   read_error = ncmpi_get_vara_float(file_id, varidp, start, count, (float *)var_data);
   ncmpi_end_indep_data(file_id);
 if (read_error != NC_NOERR) 
      terminate_with_error_msg("ERROR: Can not read the data for the variable %s \n", var_name);

}

  else if (type.atomic_type == INT)
    read_error = ncmpi_get_vara_int(file_id, varidp, start, count, var_data);
//  else if (type.atomic_type == UINT)
//    read_error = ncmpi_get_vara_uint(file_id, varidp, start, count, var_data);

//  else if (type.atomic_type == CHAR)
//    read_error = ncmpi_get_vara_char(file_id, varidp, start, count, var_data);

  else if (type.atomic_type == UCHAR)
    read_error = ncmpi_get_vara_uchar(file_id, varidp, start, count, var_data);
  else
    terminate_with_error_msg("ERROR: Unsupported type. Type = %d\n", type.atomic_type);

  if (read_error < 0)
    return -1;
  return 0;
}
예제 #2
0
//----------------------------------------------------------------
// Open the first NETCDF file and query all the types for all the variables
static void determine_var_types()
{
  assert(netcdf_file_names != 0);
  assert(netcdf_var_names != 0);
  struct Type type;
  int plist_id,i = 0,varidp,ndimsp;

  int file_id = ncmpi_open(MPI_COMM_WORLD,netcdf_file_names[0], NC_NOWRITE, MPI_INFO_NULL, &plist_id);

 if (file_id != NC_NOERR)
   terminate_with_error_msg("ERROR: Cannot open file %s\n", netcdf_file_names[0]);

  var_types = (struct Type *)calloc(var_count, sizeof(*var_types));

  nc_type xtypep;
  for (i = 0; i < var_count; ++i)
  {
   int dataset_id = ncmpi_inq_varid (plist_id, netcdf_var_names[i], &varidp);
   dataset_id = ncmpi_inq_vartype(plist_id,varidp, &xtypep);
   
   if (dataset_id != NC_NOERR) 
        terminate_with_error_msg("ERROR: Cannot read the datatype of the variable %s\n", netcdf_var_names[i]);


  int num_dims = ncmpi_inq_varndims(plist_id,varidp,&ndimsp);

    if (ndimsp > 3 )
    {
//TODO:probably we can make it more clever to handle more dimensions as they are not related to the variable itself on netcdf
      type.atomic_type = INVALID; // we don't support arrays of more than 3 dimension
      return;
    }
   else if (xtypep == NC_FLOAT || xtypep == NC_INT)
   {
    type.num_values = 1;
   }
  else // we don't support HD5_COMPOUND datatype for example
  {
    type.atomic_type = INVALID;
  }

  type.atomic_type = from_netcdf_atomic_type(xtypep);

    var_types[i] = type;

    if (var_types[i].atomic_type == INVALID)
      terminate_with_error_msg("ERROR: The datatype of the %s variable is not supported\n", netcdf_var_names[i]);
  }
  ncmpi_close(plist_id);
}
예제 #3
0
void BIL_Pio_read_nc_blocks(MPI_Comm all_readers_comm, MPI_Comm io_comm,
                            int num_blocks, BIL_Block* blocks) {
  int i;
  for (i = 0; i < num_blocks; i++) {
    int fp;
    BIL_Timing_fopen_start(all_readers_comm);
    assert(ncmpi_open(io_comm, blocks[i].file_name, NC_NOWRITE,
           BIL->io_hints, &fp) == NC_NOERR);
    BIL_Timing_fopen_stop(all_readers_comm);
  
    ncmpi_begin_indep_data(fp);
  
    // Find the id, type, and size of the variable.
    int var_id;
    assert(ncmpi_inq_varid(fp, blocks[i].var_name, &var_id) == NC_NOERR);
    nc_type var_type;
    assert(ncmpi_inq_vartype(fp, var_id, &var_type) == NC_NOERR);
  
    // Create extra variables specifically for the netCDF API.
    MPI_Offset nc_dim_starts[BIL_MAX_NUM_DIMS];
    MPI_Offset nc_dim_sizes[BIL_MAX_NUM_DIMS];
    int j;
    for (j = 0; j < blocks[i].num_dims; j++) {
      nc_dim_starts[j] = blocks[i].starts[j];
      nc_dim_sizes[j] = blocks[i].sizes[j];
    }
    MPI_Datatype nc_var_type;
    BIL_Pio_nc_to_mpi_type(var_type, &nc_var_type, &(blocks[i].var_size));
    
    // Allocate room for data and read it independently.
    blocks[i].data = BIL_Misc_malloc(blocks[i].total_size * blocks[i].var_size);
    BIL_Timing_io_start(all_readers_comm);
    assert(ncmpi_get_vara(fp, var_id, nc_dim_starts, nc_dim_sizes,
                          blocks[i].data, blocks[i].total_size,
                          nc_var_type) == NC_NOERR);
    BIL_Timing_io_stop(all_readers_comm,
                       blocks[i].total_size * blocks[i].var_size);
    // Clean up.
    ncmpi_end_indep_data(fp);
    ncmpi_close(fp);
  }
}
예제 #4
0
int main(int argc, char** argv)
{
    char filename[256];
    int i, j, rank, nprocs, err, nerrs=0, expected;
    int ncid, cmode, varid[2], dimid[2], req[4], st[4], *buf;
    int *buf0, *buf1, *buf2;
    size_t len;
    MPI_Offset start[2], count[2];
    MPI_Info info;

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

    /* this program is intended to run on one process */
    if (rank) goto fn_exit;

    /* get command-line arguments */
    if (argc > 2) {
        if (!rank) printf("Usage: %s [filename]\n",argv[0]);
        MPI_Finalize();
        return 1;
    }
    if (argc == 2) snprintf(filename, 256, "%s", argv[1]);
    else           strcpy(filename, "testfile.nc");

    if (rank == 0) {
        char *cmd_str = (char*)malloc(strlen(argv[0]) + 256);
        sprintf(cmd_str, "*** TESTING C   %s for writing interleaved fileviews ", basename(argv[0]));
        printf("%-66s ------ ", cmd_str);
        free(cmd_str);
    }

    MPI_Info_create(&info);
    MPI_Info_set(info, "romio_cb_write", "disable");
    MPI_Info_set(info, "ind_wr_buffer_size", "8");
    /* these 2 hints are required to cause a core dump if r1758 fix is not
     * presented */

    /* create a new file for writing ----------------------------------------*/
    cmode = NC_CLOBBER | NC_64BIT_DATA;
    err = ncmpi_create(MPI_COMM_SELF, filename, cmode, info, &ncid); CHECK_ERR

    MPI_Info_free(&info);

    /* define dimensions Y and X */
    err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]); CHECK_ERR
    err = ncmpi_def_dim(ncid, "X", NX, &dimid[1]); CHECK_ERR

    /* define 2D variables of integer type */
    err = ncmpi_def_var(ncid, "var0", NC_INT, 2, dimid, &varid[0]); CHECK_ERR
    err = ncmpi_def_var(ncid, "var1", NC_INT, 2, dimid, &varid[1]); CHECK_ERR

    /* enable fill mode */
    err = ncmpi_set_fill(ncid, NC_FILL, NULL); CHECK_ERR

    /* do not forget to exit define mode */
    err = ncmpi_enddef(ncid); CHECK_ERR

    /* now we are in data mode */
    buf = (int*) malloc(NY*NX * sizeof(int));

    /* fill the entire variable var0 with -1s */
    for (i=0; i<NY*NX; i++) buf[i] = -1;
    err = ncmpi_put_var_int_all(ncid, varid[0], buf); CHECK_ERR

    /* write 8 x 2 elements so this only interleaves the next two
     * iput requests */
    start[0] = 0; start[1] = 3;
    count[0] = 8; count[1] = 2;
    len = (size_t)(count[0] * count[1]);
    buf0 = (int*) malloc(len * sizeof(int));
    for (i=0; i<len; i++) buf0[i] = 50+i;
    err = ncmpi_iput_vara_int(ncid, varid[0], start, count, buf0, &req[0]);
    CHECK_ERR

    /* write 1 x 3 elements */
    start[0] = 1; start[1] = 8;
    count[0] = 1; count[1] = 5;
    len = (size_t)(count[0] * count[1]);
    buf1 = (int*) malloc(len * sizeof(int));
    for (i=0; i<len; i++) buf1[i] = 60+i;
    err = ncmpi_iput_vara_int(ncid, varid[0], start, count, buf1, &req[1]);
    CHECK_ERR

    /* write 1 x 3 elements */
    start[0] = 3; start[1] = 7;
    count[0] = 1; count[1] = 5;
    len = (size_t)(count[0] * count[1]);
    buf2 = (int*) malloc(len * sizeof(int));
    for (i=0; i<len; i++) buf2[i] = 70+i;
    err = ncmpi_iput_vara_int(ncid, varid[0], start, count, buf2, &req[2]);
    CHECK_ERR

    err = ncmpi_wait_all(ncid, 3, req, st); CHECK_ERR
    free(buf0); free(buf1); free(buf2);

    /* fill the entire variable var1 with -1s */
    for (i=0; i<NY*NX; i++) buf[i] = -1;
    err = ncmpi_put_var_int_all(ncid, varid[1], buf); CHECK_ERR

    /* write 8 x 2 elements so this only interleaves the next two iput
     * requests */
    start[0] = 0; start[1] = 3;
    count[0] = 8; count[1] = 2;
    len = (size_t)(count[0] * count[1]);
    buf0 = (int*) malloc(len * sizeof(int));
    for (i=0; i<count[0]*count[1]; i++) buf0[i] = 50+i;
    err = ncmpi_iput_vara_int(ncid, varid[1], start, count, buf0, &req[0]);
    CHECK_ERR

    /* rearrange buffer contents, as buf is 2D */
    for (i=0;  i<5;  i++) buf[i] = 10 + i;
    for (i=5;  i<10; i++) buf[i] = 10 + i +  5;
    for (i=10; i<15; i++) buf[i] = 10 + i + 10;
    start[0] = 6; start[1] = 7;
    count[0] = 3; count[1] = 5;
    err = ncmpi_iput_vara_int(ncid, varid[1], start, count, buf, &req[1]);
    CHECK_ERR

    for (i=15; i<20; i++) buf[i] = 10 + i - 10;
    for (i=20; i<25; i++) buf[i] = 10 + i -  5;
    start[0] = 6; start[1] = 12;
    count[0] = 2; count[1] = 5;
    err = ncmpi_iput_vara_int(ncid, varid[1], start, count, buf+15, &req[2]);
    CHECK_ERR

    for (i=25; i<30; i++) buf[i] = 10 + i;
    start[0] = 8; start[1] = 12;
    count[0] = 1; count[1] = 5;
    err = ncmpi_iput_vara_int(ncid, varid[1], start, count, buf+25, &req[3]);
    CHECK_ERR

    err = ncmpi_wait_all(ncid, 4, req, st); CHECK_ERR

    /* check if write buffer contents have been altered */
    for (i=0;  i<16; i++) CHECK_CONTENTS(buf0, 50 + i)
    for (i=0;  i<5;  i++) CHECK_CONTENTS(buf, 10 + i)
    for (i=5;  i<10; i++) CHECK_CONTENTS(buf, 10 + i +  5)
    for (i=10; i<15; i++) CHECK_CONTENTS(buf, 10 + i + 10)
    for (i=15; i<20; i++) CHECK_CONTENTS(buf, 10 + i - 10)
    for (i=20; i<25; i++) CHECK_CONTENTS(buf, 10 + i -  5)
    for (i=25; i<30; i++) CHECK_CONTENTS(buf, 10 + i)

    err = ncmpi_close(ncid); CHECK_ERR
    free(buf0);

    /* open the same file and read back for validate */
    err = ncmpi_open(MPI_COMM_SELF, filename, NC_NOWRITE, MPI_INFO_NULL,
                     &ncid); CHECK_ERR

    err = ncmpi_inq_varid(ncid, "var0", &varid[0]); CHECK_ERR
    err = ncmpi_inq_varid(ncid, "var1", &varid[1]); CHECK_ERR

    /* read the entire array */
    for (i=0; i<NY*NX; i++) buf[i] = -1;
    err = ncmpi_get_var_int_all(ncid, varid[0], buf); CHECK_ERR

    /* check if the contents of buf are expected */
    expected = 50;
    for (j=0; j<8; j++) {
        for (i=3; i<5; i++) {
            if (buf[j*NX+i] != expected) {
                printf("%d: Unexpected read buf[%d][%d]=%d, should be %d\n",
                       rank, j, i, buf[j*NX+i], expected);
                nerrs++;
            }
            expected++;
        }
    }
    expected = 60;
    j = 1;
    for (i=8; i<13; i++) {
        if (buf[j*NX+i] != expected) {
            printf("%d: Unexpected read buf[%d][%d]=%d, should be %d\n",
                   rank, j, i, buf[j*NX+i], expected);
            nerrs++;
        }
        expected++;
    }
    expected = 70;
    j = 3;
    for (i=7; i<12; i++) {
        if (buf[j*NX+i] != expected) {
            printf("%d: Unexpected read buf[%d][%d]=%d, should be %d\n",
                   rank, j, i, buf[j*NX+i], expected);
            nerrs++;
        }
        expected++;
    }

    /* initialize the contents of the array to a different value */
    for (i=0; i<NY*NX; i++) buf[i] = -1;

    /* read the entire array */
    err = ncmpi_get_var_int_all(ncid, varid[1], buf); CHECK_ERR

    /* check if the contents of buf are expected */
    expected = 10;
    for (j=6; j<9; j++) {
        for (i=7; i<17; i++) {
            if (buf[j*NX+i] != expected) {
                printf("%d: Unexpected read buf[%d]=%d, should be %d\n",
                       rank, i, buf[j*NX+i], expected);
                nerrs++;
            }
            expected++;
        }
    }
    expected = 50;
    for (j=0; j<8; j++) {
        for (i=3; i<5; i++) {
            if (buf[j*NX+i] != expected) {
                printf("%d: Unexpected read buf[%d][%d]=%d, should be %d\n",
                       rank, j, i, buf[j*NX+i], expected);
                nerrs++;
            }
            expected++;
        }
    }

    err = ncmpi_close(ncid); CHECK_ERR

    free(buf);

    /* check if PnetCDF freed all internal malloc */
    MPI_Offset malloc_size;
    err = ncmpi_inq_malloc_size(&malloc_size);
    if (err == NC_NOERR && malloc_size > 0) {
        printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n", malloc_size);
        ncmpi_inq_malloc_list();
    }

fn_exit:
    MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
    if (rank == 0) {
        if (nerrs) printf(FAIL_STR,nerrs);
        else       printf(PASS_STR);
    }

    MPI_Finalize();
    return (nerrs > 0);
}
예제 #5
0
파일: aiori-NCMPI.c 프로젝트: HPCStack/ior
IOR_offset_t
IOR_Xfer_NCMPI(int            access,
               void         * fd,
               IOR_size_t   * buffer,
               IOR_offset_t   length,
               IOR_param_t  * param)
{
    char         * bufferPtr          = (char *)buffer;
    static int     firstReadCheck     = FALSE,
                   startDataSet;
    int            var_id,
                   dim_id[NUM_DIMS];
    MPI_Offset     bufSize[NUM_DIMS],
                   offset[NUM_DIMS];
    IOR_offset_t   segmentPosition;
    int            segmentNum,
                   transferNum;

    /* Wei-keng Liao: In IOR.c line 1979 says "block size must be a multiple
       of transfer size."  Hence, length should always == param->transferSize
       below.  I leave it here to double check.
    */
    if (length != param->transferSize) {
        char errMsg[256];
        sprintf(errMsg,"length(%lld) != param->transferSize(%lld)\n",
                length, param->transferSize);
        NCMPI_CHECK(-1, errMsg);
    }

    /* determine by offset if need to start data set */
    if (param->filePerProc == TRUE) {
        segmentPosition = (IOR_offset_t)0;
    } else {
        segmentPosition = (IOR_offset_t)((rank + rankOffset) % param->numTasks)
                                        * param->blockSize;
    }
    if ((int)(param->offset - segmentPosition) == 0) {
        startDataSet = TRUE;
        /*
         * this toggle is for the read check operation, which passes through
         * this function twice; note that this function will open a data set
         * only on the first read check and close only on the second
         */
        if (access == READCHECK) {
            if (firstReadCheck == TRUE) {
                firstReadCheck = FALSE;
            } else {
                firstReadCheck = TRUE;
            }
        }
    }

    if (startDataSet == TRUE &&
        (access != READCHECK || firstReadCheck == TRUE)) {
        if (access == WRITE) {
            int numTransfers = param->blockSize / param->transferSize;

            /* Wei-keng Liao: change 1D array to 3D array of dimensions:
               [segmentCount*numTasksWorld][numTransfers][transferSize]
               Requirement: none of these dimensions should be > 4G,
            */
            NCMPI_CHECK(ncmpi_def_dim(*(int *)fd, "segments_times_np",
                        NC_UNLIMITED, &dim_id[0]),
                        "cannot define data set dimensions");
            NCMPI_CHECK(ncmpi_def_dim(*(int *)fd, "number_of_transfers",
                        numTransfers, &dim_id[1]),
                        "cannot define data set dimensions");
            NCMPI_CHECK(ncmpi_def_dim(*(int *)fd, "transfer_size",
                        param->transferSize, &dim_id[2]),
                        "cannot define data set dimensions");
            NCMPI_CHECK(ncmpi_def_var(*(int *)fd, "data_var", NC_BYTE,
                                      NUM_DIMS, dim_id, &var_id),
                        "cannot define data set variables");
            NCMPI_CHECK(ncmpi_enddef(*(int *)fd),
                        "cannot close data set define mode");
        
        } else {
            NCMPI_CHECK(ncmpi_inq_varid(*(int *)fd, "data_var", &var_id),
                        "cannot retrieve data set variable");
        }

        if (param->collective == FALSE) {
            NCMPI_CHECK(ncmpi_begin_indep_data(*(int *)fd),
                        "cannot enable independent data mode");
        }

        param->var_id = var_id;
        startDataSet = FALSE;
    }

    var_id = param->var_id;

    /* Wei-keng Liao: calculate the segment number */
    segmentNum  = param->offset / (param->numTasks * param->blockSize);

    /* Wei-keng Liao: calculate the transfer number in each block */
    transferNum = param->offset % param->blockSize / param->transferSize;

    /* Wei-keng Liao: read/write the 3rd dim of the dataset, each is of
       amount param->transferSize */
    bufSize[0] = 1;
    bufSize[1] = 1;
    bufSize[2] = param->transferSize;

    offset[0] = segmentNum * numTasksWorld + rank;
    offset[1] = transferNum;
    offset[2] = 0;

    /* access the file */
    if (access == WRITE) { /* WRITE */
        if (param->collective) {
            NCMPI_CHECK(ncmpi_put_vara_all(*(int *)fd, var_id, offset, bufSize,
                                           bufferPtr, length, MPI_BYTE),
                        "cannot write to data set");
        } else {
            NCMPI_CHECK(ncmpi_put_vara(*(int *)fd, var_id, offset, bufSize,
                                       bufferPtr, length, MPI_BYTE),
                        "cannot write to data set");
        }
    } else {               /* READ or CHECK */
        if (param->collective == TRUE) {
            NCMPI_CHECK(ncmpi_get_vara_all(*(int *)fd, var_id, offset, bufSize,
                                           bufferPtr, length, MPI_BYTE),
                        "cannot read from data set");
        } else {
            NCMPI_CHECK(ncmpi_get_vara(*(int *)fd, var_id, offset, bufSize,
                                       bufferPtr, length, MPI_BYTE),
                        "cannot read from data set");
        }
    }

    return(length);
} /* IOR_Xfer_NCMPI() */
예제 #6
0
/**
 * Read a single-precision parallel-nedcdf file.
 *
 * We assume here that localData is a scalar.
 *
 * Pnetcdf uses row-major format (same as FFTW).
 *
 * \param[in]  filename  : PnetCDF filename
 * \param[in]  starts    : offset to where to start reading data
 * \param[in]  counts    : number of elements read (3D sub-domain inside global)
 * \param[in]  gsizes    : global sizes
 * \param[out] localData : actual data buffer (size : nx*ny*nz*sizeof(float))
 *
 * localData must have been allocated prior to calling this routine.
 */
void read_pnetcdf(const std::string &filename,
		  MPI_Offset         starts[3],
		  MPI_Offset         counts[3],
		  int                gsizes[3],
		  float            *localData)
{

  int myRank;
  MPI_Comm_rank(MPI_COMM_WORLD, &myRank);

  // netcdf file id
  int ncFileId;
  int err;

  // file opening mode
  int ncOpenMode = NC_NOWRITE;

  int nbVar=1;
  int varIds[nbVar];
  MPI_Info mpi_info_used;

  /*
   * Open NetCDF file
   */
  err = ncmpi_open(MPI_COMM_WORLD, filename.c_str(), 
		   ncOpenMode,
		   MPI_INFO_NULL, &ncFileId);
  if (err != NC_NOERR) {
    printf("Error: ncmpi_open() file %s (%s)\n",filename.c_str(),ncmpi_strerror(err));
    MPI_Abort(MPI_COMM_WORLD, -1);
    exit(1);
  }

  /*
   * Query NetCDF mode
   */
  int NC_mode;
  err = ncmpi_inq_version(ncFileId, &NC_mode);
  if (myRank==0) {
    if (NC_mode == NC_64BIT_DATA)
      std::cout << "Pnetcdf Input mode : NC_64BIT_DATA (CDF-5)\n";
    else if (NC_mode == NC_64BIT_OFFSET)
      std::cout << "Pnetcdf Input mode : NC_64BIT_OFFSET (CDF-2)\n";
    else
      std::cout << "Pnetcdf Input mode : unknown\n";
  }

  /*
   * Query information about variable named "data"
   */
  {
    int ndims, nvars, ngatts, unlimited;
    err = ncmpi_inq(ncFileId, &ndims, &nvars, &ngatts, &unlimited);
    PNETCDF_HANDLE_ERROR;

    err = ncmpi_inq_varid(ncFileId, "data", &varIds[0]);
    PNETCDF_HANDLE_ERROR;
  }

  /*
   * Define expected data types (no conversion done here)
   */
  MPI_Datatype mpiDataType = MPI_FLOAT;

  /*
   * Get all the MPI_IO hints used (just in case, we want to print it after
   * reading data...
   */
  err = ncmpi_get_file_info(ncFileId, &mpi_info_used);
  PNETCDF_HANDLE_ERROR;

  /*
   * Read heavy data (take care of row-major / column major format !)
   */
  int nItems = counts[IX]*counts[IY]*counts[IZ];
  {

    err = ncmpi_get_vara_all(ncFileId,
			     varIds[0],
			     starts,
			     counts,
			     localData,
			     nItems,
			     mpiDataType);
    PNETCDF_HANDLE_ERROR;
  } // end reading heavy data

  /*
   * close the file
   */
  err = ncmpi_close(ncFileId);
  PNETCDF_HANDLE_ERROR;

} // read_pnetcdf
예제 #7
0
int main(int argc, char ** argv)
{
	int ncid, dimid, varid;
	MPI_Init(&argc, &argv);
	MPI_Datatype vtype, rtype, usertype;
	MPI_Aint lb, extent;
	int userbufsz, *userbuf, *cmpbuf, i, errs=0;
	int count = 25;
	double pi = 3.14159;
	MPI_Offset start, acount;

	ncmpi_create(MPI_COMM_WORLD, "vectors.nc", NC_CLOBBER, MPI_INFO_NULL,
			&ncid);
	ncmpi_def_dim(ncid, "50k", 1024*50, &dimid);
	ncmpi_def_var(ncid, "vector", NC_DOUBLE, 1, &dimid, &varid);

	ncmpi_enddef(ncid);


	MPI_Type_vector(VECCOUNT, BLOCKLEN, STRIDE, MPI_INT, &vtype);
	MPI_Type_create_resized(vtype, 0, STRIDE*VECCOUNT*sizeof(int), &rtype);
	MPI_Type_contiguous(count, rtype, &usertype);
	MPI_Type_commit(&usertype);

	MPI_Type_free(&vtype);
	MPI_Type_free(&rtype);

	MPI_Type_get_extent(usertype, &lb, &extent);
	userbufsz = extent;
	userbuf = malloc(userbufsz);
	cmpbuf = calloc(userbufsz, 1);
	for (i=0; i< userbufsz/sizeof(int); i++) {
		userbuf[i] = pi*i;
	}


	start = 10; acount = count*12;
	ncmpi_begin_indep_data(ncid);
	ncmpi_put_vara(ncid, varid, &start, &acount, 
			userbuf, 1, usertype);

	ncmpi_close(ncid);

	NC_CHECK(ncmpi_open(MPI_COMM_WORLD, "vectors.nc", NC_NOWRITE,
				MPI_INFO_NULL, &ncid));
	ncmpi_begin_indep_data(ncid);
	NC_CHECK(ncmpi_inq_varid(ncid, "vector", &varid));
	NC_CHECK(ncmpi_get_vara(ncid, varid, &start, &acount,
			cmpbuf, 1, usertype));
	ncmpi_close(ncid);

	for (i=0; errs < 10 &&  i < acount; i++) {
		/* vector of 4,3,5, so skip 4th and 5th items of every block */
		if (i%STRIDE >= BLOCKLEN) continue;
		if (userbuf[i] != cmpbuf[i]) {
			errs++;
			fprintf(stderr, "%d: expected 0x%x got 0x%x\n", 
					i, userbuf[i], cmpbuf[i]);
		}
	}
	free(userbuf);
	free(cmpbuf);
	MPI_Type_free(&usertype);
	MPI_Finalize();
	return 0;
}
예제 #8
0
void read_pnetcdf(const std::string &filename,
		  int                iVar,
		  ConfigMap         &configMap, 
		  HostArray<double> &localData)
{
  int myRank;
  MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
  int nbMpiProc;
  MPI_Comm_size(MPI_COMM_WORLD, &nbMpiProc);

  // netcdf file id
  int ncFileId;
  int err;
  
  // ghostWidth
  int ghostWidth = configMap.getInteger("mesh","ghostWidth",3);

  // file creation mode
  int ncOpenMode = NC_NOWRITE;
  
  int varIds[8];
  MPI_Offset starts[3], counts[3]; // read_size, sum_read_size;
  MPI_Info mpi_info_used;
  
  // domain local size
  int nx,ny,nz;

  // sizes to read
  //int nx_r,  ny_r,  nz_r;  // logical sizes / per sub-domain
  //int nx_g, ny_g, nz_g; // sizes with ghost zones included / per sub-domain

  /* read domain sizes */
  nx=configMap.getInteger("mesh","nx",32);
  ny=configMap.getInteger("mesh","ny",32);
  nz=configMap.getInteger("mesh","nz",32);

  // nx_g = nx+2*ghostWidth;
  // ny_g = ny+2*ghostWidth;
  // nz_g = nz+2*ghostWidth;

  // get input filename from configMap
  //std::string filename = configMap.getString("input", "filename", "");

  /* 
   * Open NetCDF file
   */
  err = ncmpi_open(MPI_COMM_WORLD, filename.c_str(), 
		   ncOpenMode,
		   MPI_INFO_NULL, &ncFileId);
  if (err != NC_NOERR) {
    printf("Error: ncmpi_open() file %s (%s)\n",filename.c_str(),ncmpi_strerror(err));
    MPI_Abort(MPI_COMM_WORLD, -1);
    exit(1);
  }

  /*
   * Query NetCDF mode
   */
  int NC_mode;
  err = ncmpi_inq_version(ncFileId, &NC_mode);
  if (myRank==0) {
    if (NC_mode == NC_64BIT_DATA)
      std::cout << "Pnetcdf Input mode : NC_64BIT_DATA (CDF-5)\n";
    else if (NC_mode == NC_64BIT_OFFSET)
      std::cout << "Pnetcdf Input mode : NC_64BIT_OFFSET (CDF-2)\n";
    else
      std::cout << "Pnetcdf Input mode : unknown\n";
  }

  /*
   * Query information about variables
   */
  {
    int ndims, nvars, ngatts, unlimited;
    err = ncmpi_inq(ncFileId, &ndims, &nvars, &ngatts, &unlimited);
    PNETCDF_HANDLE_ERROR;

    err = ncmpi_inq_varid(ncFileId, "rho", &varIds[ID]);
    PNETCDF_HANDLE_ERROR;
    err = ncmpi_inq_varid(ncFileId, "E", &varIds[IP]);
    PNETCDF_HANDLE_ERROR;
    err = ncmpi_inq_varid(ncFileId, "rho_vx", &varIds[IU]);
    PNETCDF_HANDLE_ERROR;
    err = ncmpi_inq_varid(ncFileId, "rho_vy", &varIds[IV]);
    PNETCDF_HANDLE_ERROR;
    err = ncmpi_inq_varid(ncFileId, "rho_vz", &varIds[IW]);
    PNETCDF_HANDLE_ERROR;    
    err = ncmpi_inq_varid(ncFileId, "Bx", &varIds[IA]);
    PNETCDF_HANDLE_ERROR;
    err = ncmpi_inq_varid(ncFileId, "By", &varIds[IB]);
    PNETCDF_HANDLE_ERROR;
    err = ncmpi_inq_varid(ncFileId, "Bz", &varIds[IC]);
    PNETCDF_HANDLE_ERROR;	
  } // end query information

  /* 
   * Define expected data types (no conversion done here)
   */
  //nc_type ncDataType;
  MPI_Datatype mpiDataType;
  
  //ncDataType  = NC_DOUBLE;
  mpiDataType = MPI_DOUBLE;

  /* 
   * Get all the MPI_IO hints used (just in case, we want to print it after 
   * reading data...
   */
  err = ncmpi_get_file_info(ncFileId, &mpi_info_used);
  PNETCDF_HANDLE_ERROR;

  /*
   * Read heavy data (take care of row-major / column major format !)
   */
  // use overlapping domains
  // counts[IZ] = nx_rg;
  // counts[IY] = ny_rg;
  // counts[IX] = nz_rg;
  
  // starts[IZ] = 0;
  // starts[IY] = 0;
  // starts[IX] = myRank*nz_r;

  counts[IZ] = nx;
  counts[IY] = ny;
  counts[IX] = nz;
  
  starts[IZ] = ghostWidth;
  starts[IY] = ghostWidth;
  starts[IX] = ghostWidth+myRank*nz;

  int nItems = counts[IX]*counts[IY]*counts[IZ];

  /*
   * Actual reading
   */
  {
    double* data;
    //data = &(localData(0,0,0,0));
    data = localData.data();
    
    err = ncmpi_get_vara_all(ncFileId, varIds[iVar], 
			     starts, counts, data, nItems, mpiDataType);
    PNETCDF_HANDLE_ERROR;

  } // end for loop reading heavy data

  /* 
   * close the file 
   */
  err = ncmpi_close(ncFileId);
  PNETCDF_HANDLE_ERROR;

} // read_pnetcdf
예제 #9
0
/*----< main() >------------------------------------------------------------*/
int main(int argc, char **argv) {

    char         filename[256];
    int          i, j, err, ncid, varid0, varid1, varid2, dimids[2], nerrs=0;
    int          rank, nprocs, debug=0, blocklengths[2], **buf, *bufptr;
    int          array_of_sizes[2], array_of_subsizes[2], array_of_starts[2];
    MPI_Offset   start[2], count[2];
    MPI_Aint     a0, a1, disps[2];
    MPI_Datatype buftype, ghost_buftype, rec_filetype, fix_filetype;

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

    if (argc > 2) {
        if (!rank) printf("Usage: %s [filename]\n",argv[0]);
        MPI_Finalize();
        return 0;
    }
    strcpy(filename, "testfile.nc");
    if (argc == 2) strcpy(filename, argv[1]);
    MPI_Bcast(filename, 256, MPI_CHAR, 0, MPI_COMM_WORLD);

    if (rank == 0) {
        char cmd_str[256];
        sprintf(cmd_str, "*** TESTING C   %s for flexible put and get ", argv[0]);
        printf("%-66s ------ ", cmd_str); fflush(stdout);
    }

    buf = (int**)malloc(NY * sizeof(int*));
    buf[0] = (int*)malloc(NY * NX * sizeof(int));
    for (i=1; i<NY; i++) buf[i] = buf[i-1] + NX;

    /* construct various MPI derived data types */

    /* construct an MPI derived data type for swapping 1st row with 2nd row */
    blocklengths[0] = blocklengths[1] = NX;
    MPI_Get_address(buf[1], &a0);
    MPI_Get_address(buf[0], &a1);
    disps[0] = 0;
    disps[1] = a1 - a0;
    bufptr = buf[1];
    err = MPI_Type_create_hindexed(2, blocklengths, disps, MPI_INT, &buftype);
    if (err != MPI_SUCCESS) printf("MPI error MPI_Type_create_hindexed\n");
    MPI_Type_commit(&buftype);

    start[0] = 0; start[1] = NX*rank;
    count[0] = 2; count[1] = NX;
    if (debug) printf("put start=%lld %lld count=%lld %lld\n",start[0],start[1],count[0],count[1]);

    /* create a file type for the fixed-size variable */
    array_of_sizes[0] = 2;
    array_of_sizes[1] = NX*nprocs;
    array_of_subsizes[0] = count[0];
    array_of_subsizes[1] = count[1];
    array_of_starts[0] = start[0];
    array_of_starts[1] = start[1];
    MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
                             array_of_starts, MPI_ORDER_C,
                             MPI_INT, &fix_filetype);
    MPI_Type_commit(&fix_filetype);

    /* create a buftype with ghost cells on each side */
    array_of_sizes[0] = count[0]+4;
    array_of_sizes[1] = count[1]+4;
    array_of_subsizes[0] = count[0];
    array_of_subsizes[1] = count[1];
    array_of_starts[0] = 2;
    array_of_starts[1] = 2;
    MPI_Type_create_subarray(2, array_of_sizes, array_of_subsizes,
                             array_of_starts, MPI_ORDER_C,
                             MPI_INT, &ghost_buftype);
    MPI_Type_commit(&ghost_buftype);

    /* create a new file for write */
    err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER, MPI_INFO_NULL,
                       &ncid); ERR

    /* define a 2D array */
    err = ncmpi_def_dim(ncid, "REC_DIM", NC_UNLIMITED, &dimids[0]); ERR
    err = ncmpi_def_dim(ncid, "X",       NX*nprocs,    &dimids[1]); ERR
    err = ncmpi_def_var(ncid, "rec_var", NC_INT, 2, dimids, &varid0); ERR
    err = ncmpi_def_var(ncid, "dummy_rec", NC_INT, 2, dimids, &varid2); ERR
    err = ncmpi_def_dim(ncid, "FIX_DIM", 2, &dimids[0]); ERR
    err = ncmpi_def_var(ncid, "fix_var", NC_INT, 2, dimids, &varid1); ERR
    err = ncmpi_enddef(ncid); ERR

    /* create a file type for the record variable */
    int *array_of_blocklengths=(int*) malloc(count[0]*sizeof(int));
    MPI_Aint *array_of_displacements=(MPI_Aint*) malloc(count[0]*sizeof(MPI_Aint));
    MPI_Offset recsize;
    err = ncmpi_inq_recsize(ncid, &recsize);
    for (i=0; i<count[0]; i++) {
        array_of_blocklengths[i] = count[1];
        array_of_displacements[i] = start[1]*sizeof(int) + recsize * i;
    }
    MPI_Type_create_hindexed(2, array_of_blocklengths, array_of_displacements,
                             MPI_INT, &rec_filetype);
    MPI_Type_commit(&rec_filetype);
    free(array_of_blocklengths);
    free(array_of_displacements);

    /* initialize the contents of the array */
    for (j=0; j<NY; j++) for (i=0; i<NX; i++) buf[j][i] = rank*100 + j*10 + i;

    /* write the record variable */
    err = ncmpi_put_vard_all(ncid, varid0, rec_filetype, bufptr, 1, buftype); ERR

    /* check if the contents of buf are altered */
    CHECK_VALUE

    /* check if root process can write to file header in data mode */
    err = ncmpi_rename_var(ncid, varid0, "rec_VAR"); ERR

    /* write the fixed-size variable */
    err = ncmpi_put_vard_all(ncid, varid1, fix_filetype, bufptr, 1, buftype); ERR

    /* check if the contents of buf are altered */
    CHECK_VALUE
 
    /* check if root process can write to file header in data mode */
    err = ncmpi_rename_var(ncid, varid0, "rec_var"); ERR

    /* test the same routines in independent data mode */
    err = ncmpi_begin_indep_data(ncid); ERR
    err = ncmpi_put_vard(ncid, varid0, rec_filetype, bufptr, 1, buftype); ERR
    CHECK_VALUE
    err = ncmpi_rename_var(ncid, varid0, "rec_VAR"); ERR
    err = ncmpi_put_vard(ncid, varid1, fix_filetype, bufptr, 1, buftype); ERR
    CHECK_VALUE
    err = ncmpi_rename_var(ncid, varid0, "rec_var"); ERR
    err = ncmpi_end_indep_data(ncid); ERR

    err = ncmpi_close(ncid); ERR

    /* open the same file and read back for validate */
    err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL,
                     &ncid); ERR

    err = ncmpi_inq_varid(ncid, "rec_var", &varid0); ERR
    err = ncmpi_inq_varid(ncid, "fix_var", &varid1); ERR

    nerrs += get_var_and_verify(ncid, varid0, start, count, buf, buftype, ghost_buftype, rec_filetype);
    nerrs += get_var_and_verify(ncid, varid1, start, count, buf, buftype, ghost_buftype, fix_filetype);

    err = ncmpi_close(ncid); ERR

    MPI_Type_free(&rec_filetype);
    MPI_Type_free(&fix_filetype);
    MPI_Type_free(&buftype);
    MPI_Type_free(&ghost_buftype);
    free(buf[0]); free(buf);

    /* check if PnetCDF freed all internal malloc */
    MPI_Offset malloc_size, sum_size;
    err = ncmpi_inq_malloc_size(&malloc_size);
    if (err == NC_NOERR) {
        MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
        if (rank == 0 && sum_size > 0)
            printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
                   sum_size);
    }

    MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
    if (rank == 0) {
        if (nerrs) printf(FAIL_STR,nerrs);
        else       printf(PASS_STR);
    }

    MPI_Finalize();
    return 0;
}
예제 #10
0
파일: tst_norm.c 프로젝트: LaHaine/ohpc
static
int tst_norm(char *filename, int cmode)
{
   int ncid, dimid, varid;
   int dimids[NDIMS];

   /* unnormalized UTF-8 encoding for Unicode 8-character "Hello" in Greek: */
   unsigned char uname_utf8[] = {
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x80,		/* COMBINING GRAVE ACCENT */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x81,		/* COMBINING ACUTE ACCENT */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x82,		/* COMBINING CIRCUMFLEX ACCENT */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x83,		/* COMBINING TILDE */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x88,		/* COMBINING DIAERESIS */
       0x41,              	/* LATIN CAPITAL LETTER A */
       0xCC, 0x8A,		/* COMBINING RING ABOVE */
       0x43,			/* LATIN CAPITAL LETTER C */
       0xCC, 0xA7,		/* COMBINING CEDILLA */
       0x45,			/* LATIN CAPITAL LETTER E */
       0xCC, 0x80,		/* COMBINING GRAVE ACCENT */
       0x45,			/* LATIN CAPITAL LETTER E */
       0xCC, 0x81,		/* COMBINING ACUTE ACCENT */
       0x45,			/* LATIN CAPITAL LETTER E */
       0xCC, 0x82,		/* COMBINING CIRCUMFLEX ACCENT */
       0x45,			/* LATIN CAPITAL LETTER E */
       0xCC, 0x88,		/* COMBINING DIAERESIS */
       0x49,			/* LATIN CAPITAL LETTER I */
       0xCC, 0x80,		/* COMBINING GRAVE ACCENT */
       0x49,			/* LATIN CAPITAL LETTER I */
       0xCC, 0x81,		/* COMBINING ACUTE ACCENT */
       0x49,			/* LATIN CAPITAL LETTER I */
       0xCC, 0x82,		/* COMBINING CIRCUMFLEX ACCENT */
       0x49,			/* LATIN CAPITAL LETTER I */
       0xCC, 0x88,		/* COMBINING DIAERESIS */
       0x4E,			/* LATIN CAPITAL LETTER N */
       0xCC, 0x83,		/* COMBINING TILDE */
       0x00
   };

   /* NFC normalized UTF-8 encoding for same Unicode string: */
   unsigned char nname_utf8[] = {
       0xC3, 0x80,	        /* LATIN CAPITAL LETTER A WITH GRAVE */
       0xC3, 0x81,	        /* LATIN CAPITAL LETTER A WITH ACUTE */
       0xC3, 0x82,	        /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
       0xC3, 0x83,	        /* LATIN CAPITAL LETTER A WITH TILDE */
       0xC3, 0x84,		/* LATIN CAPITAL LETTER A WITH DIAERESIS */
       0xC3, 0x85,		/* LATIN CAPITAL LETTER A WITH RING ABOVE */
       0xC3, 0x87,		/* LATIN CAPITAL LETTER C WITH CEDILLA */
       0xC3, 0x88,		/* LATIN CAPITAL LETTER E WITH GRAVE */
       0xC3, 0x89,		/* LATIN CAPITAL LETTER E WITH ACUTE */
       0xC3, 0x8A,		/* LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
       0xC3, 0x8B,		/* LATIN CAPITAL LETTER E WITH DIAERESIS */
       0xC3, 0x8C,		/* LATIN CAPITAL LETTER I WITH GRAVE */
       0xC3, 0x8D,		/* LATIN CAPITAL LETTER I WITH ACUTE */
       0xC3, 0x8E,		/* LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
       0xC3, 0x8F,		/* LATIN CAPITAL LETTER I WITH DIAERESIS */
       0xC3, 0x91,	        /* LATIN CAPITAL LETTER N WITH TILDE */
       0x00
   };

/* Unnormalized name used for dimension, variable, and attribute value */
#define UNAME ((char *) uname_utf8)
#define UNAMELEN (sizeof uname_utf8)
/* Normalized name */
#define NNAME ((char *) nname_utf8)
#define NNAMELEN (sizeof nname_utf8)

   char name_in[UNAMELEN + 1], strings_in[UNAMELEN + 1];
   nc_type att_type;
   MPI_Offset att_len;
   int err, dimid_in, varid_in, attnum_in;
   int attvals[] = {42};
#define ATTNUM ((sizeof attvals)/(sizeof attvals[0]))

   err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, MPI_INFO_NULL,&ncid); ERR

   /* Define dimension with unnormalized Unicode UTF-8 encoded name */
   err = ncmpi_def_dim(ncid, UNAME, NX, &dimid); ERR
   dimids[0] = dimid;

   /* Define variable with same name */
   err = ncmpi_def_var(ncid, UNAME, NC_CHAR, NDIMS, dimids, &varid); ERR

   /* Create string attribute with same value */
   err = ncmpi_put_att_text(ncid, varid, UNITS, UNAMELEN, UNAME); ERR

   /* Create int attribute with same name */
   err = ncmpi_put_att_int(ncid, varid, UNAME, NC_INT, ATTNUM, attvals); ERR

   /* Try to create dimension and variable with NFC-normalized
    * version of same name.  These should fail, as unnormalized name
    * should have been normalized in library, so these are attempts to
    * create duplicate netCDF objects. */
   if ((err = ncmpi_def_dim(ncid, NNAME, NX, &dimid)) != NC_ENAMEINUSE) {
       printf("Error at line %d: expecting error code %d but got %d\n",__LINE__,NC_ENAMEINUSE,err);
       return 1;
   }

   if ((err=ncmpi_def_var(ncid, NNAME, NC_CHAR, NDIMS, dimids, &varid)) != NC_ENAMEINUSE) {
       printf("Error at line %d: expecting error code %d but got %d\n",__LINE__,NC_ENAMEINUSE,err);
       return 1;
   }
   err = ncmpi_enddef(ncid); ERR

   /* Write string data, UTF-8 encoded, to the file */
   err = ncmpi_put_var_text_all(ncid, varid, UNAME); ERR
   err = ncmpi_close(ncid); ERR

   /* Check it out. */
   err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR
   err = ncmpi_inq_varid(ncid, UNAME, &varid); ERR
   err = ncmpi_inq_varname(ncid, varid, name_in); ERR
   err = strncmp(NNAME, name_in, NNAMELEN); ERR
   err = ncmpi_inq_varid(ncid, NNAME, &varid_in); ERR
   if ((err = ncmpi_inq_dimid(ncid, UNAME, &dimid_in)) || dimid != dimid_in)
       {printf("Error at line %d\n",__LINE__);return 1;}
   if ((err = ncmpi_inq_dimid(ncid, NNAME, &dimid_in)) || dimid != dimid_in)
       {printf("Error at line %d\n",__LINE__);return 1;}
   err = ncmpi_inq_att(ncid, varid, UNITS, &att_type, &att_len); ERR
   if ( att_type != NC_CHAR || att_len != UNAMELEN)
       {printf("Error at line %d\n",__LINE__);return 1;}
   err = ncmpi_get_att_text(ncid, varid, UNITS, strings_in); ERR
   strings_in[UNAMELEN] = '\0';
   err = strncmp(UNAME, strings_in, UNAMELEN); ERR
   if ((err = ncmpi_inq_attid(ncid, varid, UNAME, &attnum_in)) || ATTNUM != attnum_in)
       {printf("Error at line %d\n",__LINE__);return 1;}
   if ((err = ncmpi_inq_attid(ncid, varid, NNAME, &attnum_in)) || ATTNUM != attnum_in)
       {printf("Error at line %d\n",__LINE__);return 1;}
   err = ncmpi_close(ncid); ERR

   return 0;
}
예제 #11
0
/*----< main() >------------------------------------------------------------*/
int main(int argc, char **argv)
{
    int i, j, err, nerrs=0, rank, nprocs;
    int ncid, dimid[2], varid, req, status;

    MPI_Offset start[2], count[2], stride[2], imap[2];
    int   var[6][4];
    float k, rh[4][6];
    signed char  varT[4][6];
    char filename[256];

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

    if (argc > 2) {
        if (!rank) printf("Usage: %s [filename]\n",argv[0]);
        MPI_Finalize();
        return 1;
    }
    if (argc == 2) snprintf(filename, 256, "%s", argv[1]);
    else           strcpy(filename, "testfile.nc");

    if (rank == 0) {
        char *cmd_str = (char*)malloc(strlen(argv[0]) + 256);
        sprintf(cmd_str, "*** TESTING C   %s for get/put varm ", basename(argv[0]));
        printf("%-66s ------ ", cmd_str); fflush(stdout);
        free(cmd_str);
    }

#ifdef DEBUG
    if (nprocs > 1 && rank == 0)
        printf("Warning: %s is designed to run on 1 process\n", argv[0]);
#endif

    err = ncmpi_create(MPI_COMM_WORLD, filename, NC_CLOBBER | NC_64BIT_DATA,
                       MPI_INFO_NULL, &ncid); CHECK_ERR

    /* define a variable of a 6 x 4 integer array in the nc file */
    err = ncmpi_def_dim(ncid, "Y", 6, &dimid[0]); CHECK_ERR
    err = ncmpi_def_dim(ncid, "X", 4, &dimid[1]); CHECK_ERR
    err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimid, &varid); CHECK_ERR
    err = ncmpi_enddef(ncid); CHECK_ERR

    /* create a 6 x 4 integer variable in the file with contents:
           0,  1,  2,  3,
           4,  5,  6,  7,
           8,  9, 10, 11,
          12, 13, 14, 15,
          16, 17, 18, 19,
          20, 21, 22, 23
     */
    for (j=0; j<6; j++) for (i=0; i<4; i++) var[j][i] = j*4+i;

    start[0] = 0; start[1] = 0;
    count[0] = 6; count[1] = 4;
    if (rank > 0) count[0] = count[1] = 0;
    err = ncmpi_put_vara_int_all(ncid, varid, start, count, &var[0][0]); CHECK_ERR

    if (nprocs > 1) MPI_Barrier(MPI_COMM_WORLD);

    err = ncmpi_close(ncid); CHECK_ERR

    err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid); CHECK_ERR

    err = ncmpi_inq_varid(ncid, "var", &varid); CHECK_ERR

    /* read the variable back in the matrix transposed way, rh is 4 x 6 */
     count[0] = 6;  count[1] = 4;
    stride[0] = 1; stride[1] = 1;
      imap[0] = 1;   imap[1] = 6;   /* would be {4, 1} if not transposing */

    for (i=0; i<6; i++) for (j=0; j<4; j++) rh[j][i] = -1.0;

    err = ncmpi_iget_varm_float(ncid, varid, start, count, stride, imap, &rh[0][0], &req); CHECK_ERR

    err = ncmpi_wait_all(ncid, 1, &req, &status); CHECK_ERR
    err = status; CHECK_ERR

    /* check the contents of read */
    k = 0.0;
    for (i=0; i<6; i++) {
        for (j=0; j<4; j++) {
            if (rh[j][i] != k) {
#ifdef PRINT_ERR_ON_SCREEN
                printf("Error at line %d in %s: expecting rh[%d][%d]=%f but got %f\n",
                __LINE__,__FILE__,j,i,k,rh[j][i]);
#endif
                nerrs++;
                break;
            }
            k += 1.0;
        }
    }
#ifdef PRINT_ON_SCREEN
    /* print the contents of read */
    for (j=0; j<4; j++) {
        printf("[%2d]: ",j);
        for (i=0; i<6; i++) {
            printf("%5.1f",rh[j][i]);
        }
        printf("\n");
    }
#endif
    /* the stdout should be:
           [ 0]:   0.0  4.0  8.0 12.0 16.0 20.0
           [ 1]:   1.0  5.0  9.0 13.0 17.0 21.0
           [ 2]:   2.0  6.0 10.0 14.0 18.0 22.0
           [ 3]:   3.0  7.0 11.0 15.0 19.0 23.0
     */

    for (i=0; i<6; i++) for (j=0; j<4; j++) rh[j][i] = -1.0;

    err = ncmpi_get_varm_float_all(ncid, varid, start, count, stride, imap, &rh[0][0]); CHECK_ERR

    /* check the contents of read */
    k = 0.0;
    for (i=0; i<6; i++) {
        for (j=0; j<4; j++) {
            if (rh[j][i] != k) {
#ifdef PRINT_ERR_ON_SCREEN
                printf("Error at line %d in %s: expecting rh[%d][%d]=%f but got %f\n",
                __LINE__,__FILE__,j,i,k,rh[j][i]);
#endif
                nerrs++;
                break;
            }
            k += 1.0;
        }
    }
#ifdef PRINT_ON_SCREEN
    /* print the contents of read */
    for (j=0; j<4; j++) {
        printf("[%2d]: ",j);
        for (i=0; i<6; i++) {
            printf("%5.1f",rh[j][i]);
        }
        printf("\n");
    }
#endif
    /* the stdout should be:
           [ 0]:   0.0  4.0  8.0 12.0 16.0 20.0
           [ 1]:   1.0  5.0  9.0 13.0 17.0 21.0
           [ 2]:   2.0  6.0 10.0 14.0 18.0 22.0
           [ 3]:   3.0  7.0 11.0 15.0 19.0 23.0
     */


    err = ncmpi_close(ncid); CHECK_ERR

    err = ncmpi_open(MPI_COMM_WORLD, filename, NC_WRITE, MPI_INFO_NULL, &ncid); CHECK_ERR

    err = ncmpi_inq_varid(ncid, "var", &varid); CHECK_ERR

    /* testing get_varm(), first zero-out the variable in the file */
    memset(&var[0][0], 0, 6*4*sizeof(int));
    start[0] = 0; start[1] = 0;
    count[0] = 6; count[1] = 4;
    if (rank > 0) count[0] = count[1] = 0;
    err = ncmpi_put_vara_int_all(ncid, varid, start, count, &var[0][0]); CHECK_ERR

    /* set the contents of the write buffer varT, a 4 x 6 char array
          50, 51, 52, 53, 54, 55,
          56, 57, 58, 59, 60, 61,
          62, 63, 64, 65, 66, 67,
          68, 69, 70, 71, 72, 73
     */
    for (j=0; j<4; j++) for (i=0; i<6; i++) varT[j][i] = j*6+i + 50;

    /* write varT to the NC variable in the matrix transposed way */
    start[0]  = 0; start[1]  = 0;
    count[0]  = 6; count[1]  = 4;
    stride[0] = 1; stride[1] = 1;
    imap[0]   = 1; imap[1]   = 6;   /* would be {4, 1} if not transposing */
    if (rank > 0) count[0] = count[1] = 0;

    err = ncmpi_iput_varm_schar(ncid, varid, start, count, stride, imap, &varT[0][0], &req); CHECK_ERR

    err = ncmpi_wait_all(ncid, 1, &req, &status); CHECK_ERR
    err = status; CHECK_ERR

    /* the output from command "ncmpidump -v var test.nc" should be:
           var =
            50, 56, 62, 68,
            51, 57, 63, 69,
            52, 58, 64, 70,
            53, 59, 65, 71,
            54, 60, 66, 72,
            55, 61, 67, 73 ;
     */

    /* check if the contents of write buffer have been altered */
    for (j=0; j<4; j++) {
        for (i=0; i<6; i++) {
            if (varT[j][i] != j*6+i + 50) {
#ifdef PRINT_ERR_ON_SCREEN
                /* this error is a pnetcdf internal error, if occurs */
                printf("Error at line %d in %s: expecting varT[%d][%d]=%d but got %d\n",
                __LINE__,__FILE__,j,i,j*6+i + 50,varT[j][i]);
#endif
                nerrs++;
                break;
            }
        }
    }
    err = ncmpi_put_varm_schar_all(ncid, varid, start, count, stride, imap, &varT[0][0]); CHECK_ERR

    /* check if the contents of write buffer have been altered */
    for (j=0; j<4; j++) {
        for (i=0; i<6; i++) {
            if (varT[j][i] != j*6+i + 50) {
#ifdef PRINT_ERR_ON_SCREEN
                /* this error is a pnetcdf internal error, if occurs */
                printf("Error at line %d in %s: expecting varT[%d][%d]=%d but got %d\n",
                __LINE__,__FILE__,j,i,j*6+i + 50,varT[j][i]);
#endif
                nerrs++;
                break;
            }
        }
    }

    err = ncmpi_close(ncid); CHECK_ERR

    /* check if PnetCDF freed all internal malloc */
    MPI_Offset malloc_size, sum_size;
    err = ncmpi_inq_malloc_size(&malloc_size);
    if (err == NC_NOERR) {
        MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
        if (rank == 0 && sum_size > 0)
            printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
                   sum_size);
        if (malloc_size > 0) ncmpi_inq_malloc_list();
    }

    MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
    if (rank == 0) {
        if (nerrs) printf(FAIL_STR,nerrs);
        else       printf(PASS_STR);
    }

    MPI_Finalize();
    return (nerrs > 0);
}
예제 #12
0
int
main(int argc, char **argv)
{
   int rank, nprocs, ncid, pres_varid, temp_varid;
   int lat_varid, lon_varid;

   /* The start and count arrays will tell the netCDF library where to
      read our data. */
   MPI_Offset start[NDIMS], count[NDIMS];

   /* Program variables to hold the data we will read. We will only
      need enough space to hold one timestep of data; one record. */
   float **pres_in=NULL; /* [NLVL/nprocs][NLAT][NLON] */
   float **temp_in=NULL; /* [NLVL/nprocs][NLAT][NLON] */

   /* These program variables hold the latitudes and longitudes. */
   float lats[NLAT], lons[NLON];

   /* Loop indexes. */
   int lvl, lat, lon, rec, i = 0;

   /* Error handling. */
   int err, nerrs=0;

   char *filename = FILE_NAME;

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

   if (argc > 2) {
       if (!rank) printf("Usage: %s [filename]\n",argv[0]);
       MPI_Finalize();
       return 1;
   }
   if (argc == 2) filename = argv[1];

   if (rank == 0) {
       char *cmd_str = (char*)malloc(strlen(argv[0]) + 256);
       sprintf(cmd_str, "*** TESTING C   %s for reading file", basename(argv[0]));
       printf("%-66s ------ ", cmd_str);
       free(cmd_str);
   }

   /* Open the file. */
   err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, MPI_INFO_NULL, &ncid);
   CHECK_ERR

   /* Get the varids of the latitude and longitude coordinate
    * variables. */
   err = ncmpi_inq_varid(ncid, LAT_NAME, &lat_varid);
   CHECK_ERR
   err = ncmpi_inq_varid(ncid, LON_NAME, &lon_varid);
   CHECK_ERR

   /* Read the coordinate variable data. */
   memset(lats, 0, sizeof(float)*NLAT);
   memset(lons, 0, sizeof(float)*NLON);
   err = ncmpi_get_var_float_all(ncid, lat_varid, &lats[0]);
   CHECK_ERR
   err = ncmpi_get_var_float_all(ncid, lon_varid, &lons[0]);
   CHECK_ERR

   /* Check the coordinate variable data. */
   for (lat = 0; lat < NLAT; lat++)
      if (lats[lat] != START_LAT + 5.*lat) {
          printf("\nError at line %d in %s: expect %e but got %e\n", __LINE__,__FILE__, START_LAT+5.*lat,lats[lat]);
	  nerrs++;
          goto fn_exit;
      }
   for (lon = 0; lon < NLON; lon++)
      if (lons[lon] != START_LON + 5.*lon) {
          printf("\nError at line %d in %s: expect %e but got %e\n", __LINE__,__FILE__, START_LON+5.*lon,lons[lon]);
	  nerrs++;
          goto fn_exit;
      }

   /* Get the varids of the pressure and temperature netCDF
    * variables. */
   err = ncmpi_inq_varid(ncid, PRES_NAME, &pres_varid);
   CHECK_ERR
   err = ncmpi_inq_varid(ncid, TEMP_NAME, &temp_varid);
   CHECK_ERR

   /* Read the data. Since we know the contents of the file we know
    * that the data arrays in this program are the correct size to
    * hold one timestep. */
   count[0] = 1;
   count[2] = NLAT;
   count[3] = NLON;
   start[2] = 0;
   start[3] = 0;

   /* divide NLVL dimension among processes */
   count[1] = NLVL / nprocs;
   start[1] = count[1] * rank;
   if (rank < NLVL % nprocs) {
       start[1] += rank;
       count[1]++;
   }
   else {
       start[1] += NLVL % nprocs;
   }
   if (count[1] == 0) start[1] = 0;

   /* allocate read buffers */
   pres_in = (float**) malloc(count[1]*2 * sizeof(float*));
   temp_in = pres_in + count[1];
   if (count[1] > 0) {
       pres_in[0] = (float*) malloc(count[1]*2 * NLAT*NLON * sizeof(float));
       temp_in[0] = pres_in[0] + count[1] * NLAT*NLON;
       for (i=1; i<count[1]; i++) {
           pres_in[i] = pres_in[i-1] + NLAT*NLON;
           temp_in[i] = temp_in[i-1] + NLAT*NLON;
       }
   }

   /* Read and check one record at a time. */
   for (rec = 0; rec < NREC; rec++)
   {
      start[0] = rec;
      err = ncmpi_get_vara_float_all(ncid, pres_varid, start, count, &pres_in[0][0]);
      CHECK_ERR
      err = ncmpi_get_vara_float_all(ncid, temp_varid, start, count, &temp_in[0][0]);
      CHECK_ERR

      /* Check the data. */
      i = (int)start[1] * NLAT * NLON;
      for (lvl=0; lvl<count[1]; lvl++)
	 for (lat = 0; lat < NLAT; lat++)
	    for (lon = 0; lon < NLON; lon++) {
	       if (pres_in[lvl][lat*NLON+lon] != SAMPLE_PRESSURE + i) {
                  printf("\nError at line %d in %s: expect %e but got %e\n", __LINE__,__FILE__, SAMPLE_PRESSURE+i,pres_in[lvl][lat*NLON+lon]);
		  nerrs++;
		  goto fn_exit;
               }
	       if (temp_in[lvl][lat*NLON+lon] != SAMPLE_TEMP + i) {
                  printf("\nError at line %d in %s: expect %e but got %e\n", __LINE__,__FILE__, SAMPLE_TEMP+i,temp_in[lvl][lat*NLON+lon]);
		  nerrs++;
		  goto fn_exit;
               }
	       i++;
	    }

   } /* next record */

fn_exit:
    /* Close the file. */
    err = ncmpi_close(ncid);
    CHECK_ERR

    if (pres_in != NULL) {
       if (pres_in[0] != NULL) free(pres_in[0]);
       free(pres_in);
    }

    /* check if there is any malloc residue */
    MPI_Offset malloc_size, sum_size;
    err = ncmpi_inq_malloc_size(&malloc_size);
    if (err == NC_NOERR) {
        MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
        if (rank == 0 && sum_size > 0)
            printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
                   sum_size);
    }

    MPI_Allreduce(MPI_IN_PLACE, &nerrs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
    if (rank == 0) {
        if (nerrs) printf(FAIL_STR,nerrs);
        else       printf(PASS_STR);
    }

   MPI_Finalize();
   return (nerrs > 0);
}
예제 #13
0
파일: io.c 프로젝트: gcasey/cosmotools
/*
  reads input in pnetcdf format

  nblocks: (output) local number of blocks
  tot_blocks: (output) total number of blocks
  vblocks: (output) pointer to array of vblocks
  in_file: input file name
  comm: MPI communicator
  gids: (output) gids of local blocks (allocated by this function)
  num_neighbors: (output) number of neighbors for each local block
   (allocated by this function)
  neighbors: (output) gids of neighbors of each local block
   (allocated by this function)

  side effects: allocates vblocks, gids, num_neighbors, neighbors

*/
void pnetcdf_read(int *nblocks, int *tot_blocks, struct vblock_t ***vblocks,
      char *in_file, MPI_Comm comm, int *gids, int *num_neighbors,
      int **neighbors) {

#ifdef USEPNETCDF
  int err;
  int ncid, varids[23], dimids[8];
  MPI_Offset start[2], count[2];
  nc_type type;
  int ndims, natts;
  int dims[2];
  int rank, groupsize; /* MPI usual */

  /* open file for reading */
  err = ncmpi_open(comm, in_file, NC_NOWRITE, MPI_INFO_NULL, &ncid); ERR;

  err = ncmpi_inq_varid(ncid, "block_off_num_verts", &varids[5]); ERR;
  err = ncmpi_inq_varid(ncid, "block_off_num_complete_cells", &varids[6]); ERR;
  err = ncmpi_inq_varid(ncid, "block_off_tot_num_cell_faces", &varids[7]); ERR;
  err = ncmpi_inq_varid(ncid, "block_off_tot_num_face_verts", &varids[8]); ERR;
  err = ncmpi_inq_varid(ncid, "block_off_num_orig_particles", &varids[9]); ERR;

  /* get number of blocks */
  MPI_Offset num_g_blocks; /* 64 bit version of tot_blcoks */
  err = ncmpi_inq_dimlen(ncid, dimids[0], &num_g_blocks); ERR;
  *tot_blocks = num_g_blocks;
  MPI_Comm_rank(comm, &rank);
  MPI_Comm_size(comm, &groupsize);
  int start_block_ofst =  rank * (*tot_blocks / groupsize);
  *nblocks = (rank < groupsize - 1 ? (*tot_blocks / groupsize) :
        *tot_blocks - (rank * *tot_blocks / groupsize));

  /* block offsets */
  int64_t *block_ofsts = (int64_t*)malloc(*tot_blocks * sizeof(int64_t));
  *vblocks = (struct vblock_t**)malloc(*nblocks * sizeof(struct vblock_t*));

  /* read all blocks */
  gids = (int *)malloc(*nblocks * sizeof(int));
  num_neighbors = (int *)malloc(*nblocks * sizeof(int));
  neighbors = (int **)malloc(*nblocks * sizeof(int *));
  int b;
  for (b = 0; b < *nblocks; b++) {

    struct vblock_t* v = (struct vblock_t*)malloc(sizeof(struct vblock_t));

    /* quantities */
    start[0] = start_block_ofst + b;
    count[0] = 1;
    err = ncmpi_inq_varid(ncid, "num_verts", &varids[0]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[0], start, count,
         &(v->num_verts)); ERR;
    err = ncmpi_inq_varid(ncid, "num_complete_cells", &varids[1]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[1], start, count,
         &(v->num_complete_cells)); ERR;
    err = ncmpi_inq_varid(ncid, "tot_num_cell_faces", &varids[2]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[2], start, count,
         &(v->tot_num_cell_faces)); ERR;
    err = ncmpi_inq_varid(ncid, "tot_num_face_verts", &varids[3]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[3], start, count,
         &(v->tot_num_face_verts)); ERR;
    err = ncmpi_inq_varid(ncid, "num_orig_particles", &varids[4]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[4], start, count,
         &(v->num_orig_particles)); ERR;
    err = ncmpi_inq_varid(ncid, "neighbors", &varids[21]); ERR;
    err = ncmpi_inq_var(ncid, varids[21], 0, &type, &ndims,
      dimids, &natts);

    /* block bounds */
    start[0] = start_block_ofst + b;
    start[1] = 0;
    count[0] = 1;
    count[1] = 3;
    err = ncmpi_inq_varid(ncid, "mins", &varids[11]); ERR;
    err = ncmpi_get_vara_float_all(ncid, varids[11], start, count,
           v->mins); ERR;
    err = ncmpi_inq_varid(ncid, "maxs", &varids[12]); ERR;
    err = ncmpi_get_vara_float_all(ncid, varids[12], start, count,
           v->maxs); ERR;

    /* save_verts */
    start[0] = 0;
    count[0] = *tot_blocks;
    err = ncmpi_get_vara_longlong_all(ncid, varids[5], start, count,
              block_ofsts); ERR;
    v->save_verts = (float *)malloc(v->num_verts * 3 * sizeof(float));
    start[0] = block_ofsts[start_block_ofst + b];
    start[1] = 0;
    count[0] = v->num_verts;
    count[1] = 3;
    err = ncmpi_inq_varid(ncid, "save_verts", &varids[13]); ERR;
    err = ncmpi_get_vara_float_all(ncid, varids[13], start, count,
           v->save_verts); ERR;

    /* sites */
    start[0] = 0;
    count[0] = *tot_blocks;
    err = ncmpi_get_vara_longlong_all(ncid, varids[9], start, count,
              block_ofsts); ERR;
    v->sites = (float *)malloc(v->num_orig_particles * 3 * sizeof(float));
    start[0] = block_ofsts[start_block_ofst + b];
    start[1] = 0;
    count[0] = v->num_orig_particles;
    count[1] = 3;
    err = ncmpi_inq_varid(ncid, "sites", &varids[14]); ERR;
    err = ncmpi_get_vara_float_all(ncid, varids[14], start, count,
           v->sites); ERR;

    /* complete cells */
    start[0] = 0;
    count[0] = *tot_blocks;
    err = ncmpi_get_vara_longlong_all(ncid, varids[6], start, count,
              block_ofsts); ERR;
    v->complete_cells = (int *)malloc(v->num_complete_cells * sizeof(int));
    start[0] = block_ofsts[start_block_ofst + b];
    count[0] = v->num_complete_cells;
    err = ncmpi_inq_varid(ncid, "complete_cells", &varids[15]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[15], start, count,
         v->complete_cells); ERR;

    /* areas, uses same block offsets as complete cells */
    v->areas = (float *)malloc(v->num_complete_cells * sizeof(float));
    start[0] = block_ofsts[start_block_ofst + b];
    count[0] = v->num_complete_cells;
    err = ncmpi_inq_varid(ncid, "areas", &varids[16]); ERR;
    err = ncmpi_get_vara_float_all(ncid, varids[16], start, count,
           v->areas); ERR;

    /* volumes, uses same block offsets as complete cells */
    v->vols = (float *)malloc(v->num_complete_cells * sizeof(float));
    start[0] = block_ofsts[start_block_ofst + b];
    count[0] = v->num_complete_cells;
    err = ncmpi_inq_varid(ncid, "vols", &varids[17]); ERR;
    err = ncmpi_get_vara_float_all(ncid, varids[17], start, count,
           v->vols); ERR;

    /* num_cell_faces, uses same block offsets as complete cells */
    v->num_cell_faces = (int *)malloc(v->num_complete_cells * sizeof(int));
    start[0] = block_ofsts[start_block_ofst + b];
    count[0] = v->num_complete_cells;
    err = ncmpi_inq_varid(ncid, "num_cell_faces", &varids[18]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[18], start, count,
         v->num_cell_faces); ERR;

    /* num_face_verts */
    start[0] = 0;
    count[0] = *tot_blocks;
    err = ncmpi_get_vara_longlong_all(ncid, varids[7], start, count,
              block_ofsts); ERR;
    v->num_face_verts = (int *)malloc(v->tot_num_cell_faces * sizeof(int));
    start[0] = block_ofsts[start_block_ofst + b];
    count[0] = v->tot_num_cell_faces;
    err = ncmpi_inq_varid(ncid, "num_face_verts", &varids[19]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[19], start, count,
         v->num_face_verts); ERR;

    /* face_verts */
    start[0] = 0;
    count[0] = *tot_blocks;
    err = ncmpi_get_vara_longlong_all(ncid, varids[8], start, count,
              block_ofsts); ERR;
    v->face_verts = (int *)malloc(v->tot_num_face_verts * sizeof(int));
    start[0] = block_ofsts[start_block_ofst + b];
    count[0] = v->tot_num_face_verts;
    err = ncmpi_inq_varid(ncid, "face_verts", &varids[20]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[20], start, count,
         v->face_verts); ERR;

    /* neighbors */
    MPI_Offset n; /* temporary 64-bit version of number of neighbors */
    err = ncmpi_inq_varid(ncid, "neighbors", &varids[21]); ERR;
    err = ncmpi_inq_var(ncid, varids[2], 0, &type, &ndims,
      dims, &natts); ERR;
    err = ncmpi_inq_dimlen(ncid, dims[0], &n); ERR;
    num_neighbors[b] = n;
    neighbors[b] = (int *)malloc(num_neighbors[b] * sizeof(int));
    start[0] = start_block_ofst + b;
    count[0] = num_neighbors[b];
    err = ncmpi_get_vara_int_all(ncid, varids[21], start, count,
         neighbors[b]); ERR;

    /* gids */
    start[0] = start_block_ofst + b;
    count[0] = 1;
    err = ncmpi_inq_varid(ncid, "g_block_ids", &varids[22]); ERR;
    err = ncmpi_get_vara_int_all(ncid, varids[22], start, count,
         &gids[b]); ERR;

    (*vblocks)[b] = v;

  }

  /* cleanup */
  err = ncmpi_close(ncid); ERR;
  free(block_ofsts);
#endif
}
예제 #14
0
int main(int argc, char** argv)
{
    extern int optind;
    char filename[256];
    int i, j, verbose=1, rank, nprocs, err, nerrs=0;
    int myNX, G_NX, myOff, num_reqs;
    int ncid, cmode, varid, dimid[2], *reqs, *sts, **buf;
    MPI_Offset start[2], count[2];
    MPI_Info info;

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

    /* get command-line arguments */
    while ((i = getopt(argc, argv, "hq")) != EOF)
        switch(i) {
            case 'q': verbose = 0;
                      break;
            case 'h':
            default:  if (rank==0) usage(argv[0]);
                      MPI_Finalize();
                      return 1;
        }
    if (argv[optind] == NULL) strcpy(filename, "testfile.nc");
    else                      snprintf(filename, 256, "%s", argv[optind]);

    /* set an MPI-IO hint to disable file offset alignment for fixed-size
     * variables */
    MPI_Info_create(&info);
    MPI_Info_set(info, "nc_var_align_size", "1");

    cmode = NC_CLOBBER | NC_64BIT_DATA;
    err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid);
    ERR

    MPI_Info_free(&info);

    /* the global array is NY * (NX * nprocs) */
    G_NX  = NX * nprocs;
    myOff = NX * rank;
    myNX  = NX;
    if (verbose) printf("%2d: myOff=%3d myNX=%3d\n",rank,myOff,myNX);

    err = ncmpi_def_dim(ncid, "Y", NY, &dimid[0]);
    ERR
    err = ncmpi_def_dim(ncid, "X", G_NX, &dimid[1]);
    ERR
    err = ncmpi_def_var(ncid, "var", NC_INT, 2, dimid, &varid);
    ERR
    err = ncmpi_enddef(ncid);
    ERR

    /* First, fill the entire array with zeros, using a blocking I/O.
       Every process writes a subarray of size NY * myNX */
    buf    = (int**) malloc(myNX * sizeof(int*));
    buf[0] = (int*)  calloc(NY * myNX, sizeof(int));
    start[0] = 0;   start[1] = myOff;
    count[0] = NY;  count[1] = myNX;
    err = ncmpi_put_vara_int_all(ncid, varid, start, count, buf[0]);
    free(buf[0]);

    /* initialize the buffer with rank ID. Also make the case interesting,
       by allocating buffers separately */
    for (i=0; i<myNX; i++) {
        buf[i] = (int*) malloc(NY * sizeof(int));
        for (j=0; j<NY; j++) buf[i][j] = rank;
    }

    reqs = (int*) malloc(myNX * sizeof(int));
    sts  = (int*) malloc(myNX * sizeof(int));

    /* each proc writes myNX single columns of the 2D array */
    start[0]  = 0;   start[1] = rank;
    count[0]  = NY;  count[1] = 1;
    if (verbose)
        printf("%2d: start=%3lld %3lld count=%3lld %3lld\n",
               rank, start[0],start[1], count[0],count[1]);

    num_reqs = 0;
    for (i=0; i<myNX; i++) {
        err = ncmpi_iput_vara_int(ncid, varid, start, count, buf[i],
                                  &reqs[num_reqs++]);
        ERR
        start[1] += nprocs;
    }
    err = ncmpi_wait_all(ncid, num_reqs, reqs, sts);
    ERR

    /* check status of all requests */
    for (i=0; i<num_reqs; i++)
        if (sts[i] != NC_NOERR)
            printf("Error at line %d in %s: nonblocking write fails on request %d (%s)\n",
                   __LINE__,__FILE__,i, ncmpi_strerror(sts[i]));

    err = ncmpi_close(ncid); ERR

    /* read back using the same access pattern */
    err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, info, &ncid); ERR

    err = ncmpi_inq_varid(ncid, "var", &varid); ERR

    for (i=0; i<myNX; i++)
        for (j=0; j<NY; j++) buf[i][j] = -1;

    /* each proc reads myNX single columns of the 2D array */
    start[0]  = 0;   start[1] = rank;
    count[0]  = NY;  count[1] = 1;

    num_reqs = 0;
    for (i=0; i<myNX; i++) {
        err = ncmpi_iget_vara_int(ncid, varid, start, count, buf[i],
                                  &reqs[num_reqs++]);
        ERR
        start[1] += nprocs;
    }
    err = ncmpi_wait_all(ncid, num_reqs, reqs, sts);
    ERR

    /* check status of all requests */
    for (i=0; i<num_reqs; i++)
        if (sts[i] != NC_NOERR)
            printf("Error at line %d in %s: nonblocking write fails on request %d (%s)\n",
                   __LINE__,__FILE__,i, ncmpi_strerror(sts[i]));

    for (i=0; i<myNX; i++) {
        for (j=0; j<NY; j++)
            if (buf[i][j] != rank)
                printf("Error at line %d in %s: expect buf[%d][%d]=%d but got %d\n",
                __LINE__,__FILE__,i,j,rank,buf[i][j]);
    }

    err = ncmpi_close(ncid);
    ERR

    free(sts);
    free(reqs);
    for (i=0; i<myNX; i++) free(buf[i]);
    free(buf);

    /* check if there is any PnetCDF internal malloc residue */
    MPI_Offset malloc_size, sum_size;
    err = ncmpi_inq_malloc_size(&malloc_size);
    if (err == NC_NOERR) {
        MPI_Reduce(&malloc_size, &sum_size, 1, MPI_OFFSET, MPI_SUM, 0, MPI_COMM_WORLD);
        if (rank == 0 && sum_size > 0)
            printf("heap memory allocated by PnetCDF internally has %lld bytes yet to be freed\n",
                   sum_size);
    }

    MPI_Finalize();
    return (nerrs > 0);
}
예제 #15
0
/*----< main() >--------------------------------------------------------------*/
int main(int argc, char **argv)
{
    int i, j, c, err, rank, nprocs, verbose, quiet;
    int ncid1, ndims1, nvars1, natts1, unlimdimid1, *dimids1;
    int ncid2, ndims2, nvars2, natts2, unlimdimid2, *dimids2;
    char *name1, *name2;
    MPI_Offset *shape=NULL, varsize, *start=NULL;
    MPI_Offset attlen1, dimlen1, attlen2, dimlen2;
    nc_type type1, type2;
    MPI_Comm comm=MPI_COMM_WORLD;
    int nvars, check_header, check_variable_list, check_entire_file;
    long long numVarDIFF=0, numHeadDIFF=0, varDIFF, numDIFF;
    struct vspec var_list;
    extern char *optarg;
    extern int optind;
    MPI_Info info;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(comm, &nprocs);
    MPI_Comm_rank(comm, &rank);

    progname            = argv[0];
    verbose             = 0;
    quiet               = 0;
    check_header        = 0;
    check_variable_list = 0;
    check_entire_file   = 0;
    var_list.names      = NULL;
    var_list.nvars      = 0;

    while ((c = getopt(argc, argv, "bhqv:")) != -1)
        switch(c) {
            case 'h':               /* compare header only */
                check_header = 1;
                break;
            case 'v':               /* variable names */
                /* make list of names of variables specified */
                get_var_names(optarg, &var_list);
                check_variable_list = 1;
                break;
            case 'b':
                verbose = 1;
                break;
            case 'q':
                quiet = 1;
                break;
            case '?':
                usage(rank, argv[0]);
                break;
        }

    /* quiet overwrites verbose */
    if (quiet) verbose = 0;

    if (argc - optind != 2) usage(rank, argv[0]);

    if (check_header == 0 && check_variable_list == 0) {
        check_entire_file = 1;
        check_header      = 1;
    }

    name1   = (char*) malloc(NC_MAX_NAME);
    if (!name1) OOM_ERROR
    name2   = (char*) malloc(NC_MAX_NAME);
    if (!name2) OOM_ERROR

    /* Nov. 18, 2014 -- disable subfiling as it does not correctly handle the
     * cases when  nprocs < num_subfiles */
    MPI_Info_create (&info);
    MPI_Info_set (info, "pnetcdf_subfiling", "disable");

    /* open files */
    err = ncmpi_open(comm, argv[optind], NC_NOWRITE, info, &ncid1);
    HANDLE_ERROR
    err = ncmpi_open(comm, argv[optind+1], NC_NOWRITE, info, &ncid2);
    HANDLE_ERROR

    MPI_Info_free(&info);

    /* check header */
    if (check_header && rank == 0) { /* only root checks header */
        int attnump;

        err = ncmpi_inq(ncid1, &ndims1, &nvars1, &natts1, &unlimdimid1);
        HANDLE_ERROR
        err = ncmpi_inq(ncid2, &ndims2, &nvars2, &natts2, &unlimdimid2);
        HANDLE_ERROR
        if (ndims1 != ndims2) { /* check number of dimensions if equal */
            if (!quiet) printf("DIFF: number of dimensions (%d) != (%d)\n",ndims1, ndims2);
            numHeadDIFF++;
        }
        else if (verbose)
            printf("SAME: number of dimensions (%d)\n",ndims1);
        if (nvars1 != nvars2) { /* check number of variables if equal */
            if (!quiet) printf("DIFF: number of variables (%d) != (%d)\n",nvars1, nvars2);
            numHeadDIFF++;
        }
        else if (verbose)
            printf("SAME: number of variables (%d)\n",nvars1);
        if (natts1 != natts2) { /* check number of global attributes if equal */
            if (!quiet) printf("DIFF: number of global attributes (%d) != (%d)\n",natts1, natts2);
            numHeadDIFF++;
        }
        else if (verbose)
            printf("SAME: number of global attributes (%d)\n",natts1);

        /* Compare global attributes, assume CHAR attributes. */
        for (i=0; i<natts1; i++) { /* check what's in file1 also in file2 */
            err = ncmpi_inq_attname(ncid1, NC_GLOBAL, i, name1);
            HANDLE_ERROR
            /* find the attr with the same name from ncid2 */
            err = ncmpi_inq_attid(ncid2, NC_GLOBAL, name1, &attnump);
            if (err == NC_ENOTATT) {
                if (!quiet) printf("DIFF: global attribute \"%s\" not found in file %s\n",
                       name1,argv[optind+1]);
                numHeadDIFF++;
                continue;
            }

            err = ncmpi_inq_att(ncid1, NC_GLOBAL, name1, &type1, &attlen1);
            HANDLE_ERROR
            err = ncmpi_inq_att(ncid2, NC_GLOBAL, name1, &type2, &attlen2);
            HANDLE_ERROR
            if (type1 != type2) {
                if (!quiet) printf("DIFF: global attribute \"%s\" data type (%s) != (%s)\n",
                       name1,get_type(type1),get_type(type2));
                numHeadDIFF++;
                continue;
            }
            else if (verbose) {
                printf("Global attribute \"%s\":\n",name1);
                printf("\tSAME: data type (%s)\n",get_type(type1));
            }

            if (attlen1 != attlen2) {
                if (!quiet) printf("DIFF: global attribute \"%s\" length (%lld) != (%lld)\n",
                       name1,attlen1,attlen2);
                numHeadDIFF++;
                continue;
            }
            else if (verbose)
                printf("\tSAME: length (%lld)\n",attlen1);

            switch (type1) {
                case NC_CHAR:   CHECK_GLOBAL_ATT_DIFF(char,   ncmpi_get_att_text,      NC_CHAR)
                case NC_SHORT:  CHECK_GLOBAL_ATT_DIFF(short,  ncmpi_get_att_short,     NC_SHORT)
                case NC_INT:    CHECK_GLOBAL_ATT_DIFF(int,    ncmpi_get_att_int,       NC_INT)
                case NC_FLOAT:  CHECK_GLOBAL_ATT_DIFF(float,  ncmpi_get_att_float,     NC_FLOAT)
                case NC_DOUBLE: CHECK_GLOBAL_ATT_DIFF(double, ncmpi_get_att_double,    NC_DOUBLE)
                case NC_UBYTE:  CHECK_GLOBAL_ATT_DIFF(ubyte,  ncmpi_get_att_uchar,     NC_UBYTE)
                case NC_USHORT: CHECK_GLOBAL_ATT_DIFF(ushort, ncmpi_get_att_ushort,    NC_USHORT)
                case NC_UINT:   CHECK_GLOBAL_ATT_DIFF(uint,   ncmpi_get_att_uint,      NC_UINT)
                case NC_INT64:  CHECK_GLOBAL_ATT_DIFF(int64,  ncmpi_get_att_longlong,  NC_INT64)
                case NC_UINT64: CHECK_GLOBAL_ATT_DIFF(uint64, ncmpi_get_att_ulonglong, NC_UINT64)
                default: ; /* TODO: handle unexpected types */
            }
        }
        for (i=0; i<natts2; i++) { /* check attributes in file2 but not in file1 */
            err = ncmpi_inq_attname(ncid2, NC_GLOBAL, i, name2);
            HANDLE_ERROR
            /* find the attr with the same name from ncid1 */
            if (ncmpi_inq_attid(ncid1, NC_GLOBAL, name2, &attnump) == NC_ENOTATT) {
                numHeadDIFF++;
                if (!quiet) printf("DIFF: global attribute \"%s\" not found in file %s\n",
                       name1,argv[optind]);
            }
        }

        /* Compare dimension */
        if (ndims1 && verbose)
            printf("Dimension:\n");

        for (i=0; i<ndims1; i++) { /* check dimensions in file1 also in file2 */
            int dimid;
            err = ncmpi_inq_dim(ncid1, i, name1, &dimlen1);
            HANDLE_ERROR
            /* find the dim with the same name from ncid2 */
            err = ncmpi_inq_dimid(ncid2, name1, &dimid);
            if (err == NC_EBADDIM) {
                if (!quiet) printf("DIFF: dimension \"%s\" not found in file %s\n",
                       name1,argv[optind+1]);
                numHeadDIFF++;
                continue;
            }

            err = ncmpi_inq_dimlen(ncid2, dimid, &dimlen2);
            HANDLE_ERROR
            if (dimlen1 != dimlen2) {
                /* cast to quiet warning on 32 bit platforms */
                if (!quiet) printf("DIFF: dimension \"%s\" length (%lld) != (%lld)\n",
                       name1,(long long int)dimlen1,(long long int)dimlen2);
                numHeadDIFF++;
            }
            else if (verbose)
                printf("\tSAME: dimension \"%s\" length (%lld)\n",
                       name1,(long long int)dimlen1);
        }
        for (i=0; i<ndims2; i++) { /* check dimensions in file2 but not in file1 */
            int dimid;
            err = ncmpi_inq_dim(ncid2, i, name2, &dimlen2);
            HANDLE_ERROR
            /* find the dim with the same name from ncid1 */
            if (ncmpi_inq_dimid(ncid2, name1, &dimid) == NC_EBADDIM) {
                if (!quiet) printf("DIFF: dimension \"%s\" not found in file %s\n",
                       name1,argv[optind]);
                numHeadDIFF++;
            }
        }

        /* Compare variables' metadata */
        for (i=0; i<nvars1; i++) {
            int varid;
            err = ncmpi_inq_varndims(ncid1, i, &ndims1); HANDLE_ERROR
            dimids1 = (int*) malloc((size_t)ndims1 * SIZEOF_INT);
            if (!dimids1) OOM_ERROR
            err = ncmpi_inq_var(ncid1, i, name1, &type1, &ndims1, dimids1, &natts1);
            HANDLE_ERROR
            /* find the variable with the same name from ncid2 */
            err = ncmpi_inq_varid(ncid2, name1, &varid);
            if (err == NC_ENOTVAR) {
                if (!quiet) printf("DIFF: variable \"%s\" not found in file %s\n",
                       name1,argv[optind+1]);
                numHeadDIFF++;
                numVarDIFF++;
                continue;
            }
            err = ncmpi_inq_varndims(ncid2, varid, &ndims2); HANDLE_ERROR
            dimids2 = (int*) malloc((size_t)ndims2 * SIZEOF_INT);
            if (!dimids2) OOM_ERROR
            err = ncmpi_inq_var(ncid2, varid, name2, &type2, &ndims2, dimids2, &natts2);
            HANDLE_ERROR

            if (type1 != type2) {
                if (!quiet) printf("DIFF: variable \"%s\" data type (%s) != (%s)\n",
                       name1,get_type(type1),get_type(type2));
                numHeadDIFF++;
            }
            else if (verbose) {
                printf("Variable \"%s\":\n",name1);
                printf("\tSAME: data type (%s)\n",get_type(type1));
            }

            if (ndims1 != ndims2) {
                if (!quiet) printf("DIFF: variable \"%s\" number of dimensions (%d) != (%d)\n",
                       name1,ndims1,ndims2);
                numHeadDIFF++;
            }
            else {
                if (verbose)
                    printf("\tSAME: number of dimensions (%d)\n",ndims1);

                for (j=0; j<ndims1; j++) { /* check variable's dimensionality */
                    char dimname1[NC_MAX_NAME], dimname2[NC_MAX_NAME];
                    /* get dim name for each dim ID */
                    err = ncmpi_inq_dim(ncid1, dimids1[j], dimname1, &dimlen1);
                    HANDLE_ERROR
                    err = ncmpi_inq_dim(ncid1, dimids2[j], dimname2, &dimlen2);
                    HANDLE_ERROR
                    if (verbose)
                        printf("\tdimension %d:\n",j);
                    if (strcmp(dimname1, dimname2) != 0) {
                        if (!quiet) printf("DIFF: variable \"%s\" of type \"%s\" dimension %d's name (%s) != (%s)\n",
                               name1,get_type(type1),j,dimname1,dimname2);
                        numHeadDIFF++;
                    }
                    else if (verbose)
                        printf("\t\tSAME: name (%s)\n",dimname1);
                    if (dimlen1 != dimlen2) {
                        if (!quiet) printf("DIFF: variable \"%s\" of type \"%s\" dimension %d's length (%lld) != (%lld)\n",
                               name1,get_type(type1),j,(long long int)dimlen1,(long long int)dimlen2);
                        numHeadDIFF++;
                    }
                    else if (verbose)
                        printf("\t\tSAME: length (%lld)\n",(long long int)dimlen1);
                }
            }

            if (natts1 != natts2) {
                if (!quiet) printf("DIFF: variable \"%s\" number of attributes (%d) != (%d)\n",
                       name1,natts1,natts2);
                numHeadDIFF++;
            }
            else if (verbose)
                printf("\tSAME: number of attributes (%d)\n",natts1);

            /* var attributes, assume CHAR attributes */
            for (j=0; j<natts1; j++) {
                char attrname[NC_MAX_NAME];
                err = ncmpi_inq_attname(ncid1, i, j, attrname);
                HANDLE_ERROR
                err = ncmpi_inq_att(ncid1, i, attrname, &type1, &attlen1);
                HANDLE_ERROR
                /* find the variable attr with the same name from ncid2 */
                err = ncmpi_inq_att(ncid2, varid, attrname, &type2, &attlen2);
                if (err == NC_ENOTATT) {
                    if (!quiet) printf("DIFF: variable \"%s\" attribute \"%s\" not found in file %s\n",
                           name1,attrname,argv[optind+1]);
                    numHeadDIFF++;
                    continue;
                }
                if (verbose)
                    printf("\tattribute \"%s\":\n",attrname);

                if (type1 != type2) {
                    if (!quiet) printf("DIFF: variable \"%s\" attribute \"%s\" data type (%s) != (%s)\n",
                           name1,attrname,get_type(type1),get_type(type2));
                    numHeadDIFF++;
                    continue; /* skip this attribute */
                }
                else if (verbose)
                    printf("\t\tSAME: data type (%s)\n",get_type(type1));
                if (attlen1 != attlen2) {
                    if (!quiet) printf("DIFF: variable \"%s\" attribute \"%s\" length (%lld) != (%lld)\n",
                           name1,attrname,(long long int)attlen1,(long long int)attlen2);
                    numHeadDIFF++;
                    continue; /* skip this attribute */
                }
                else if (verbose)
                    printf("\t\tSAME: length (%lld)\n",(long long int)attlen1);

                switch (type1) {
                    case NC_CHAR:   CHECK_VAR_ATT_DIFF(char,   ncmpi_get_att_text,      NC_CHAR)
                    case NC_SHORT:  CHECK_VAR_ATT_DIFF(short,  ncmpi_get_att_short,     NC_SHORT)
                    case NC_INT:    CHECK_VAR_ATT_DIFF(int,    ncmpi_get_att_int,       NC_INT)
                    case NC_FLOAT:  CHECK_VAR_ATT_DIFF(float,  ncmpi_get_att_float,     NC_FLOAT)
                    case NC_DOUBLE: CHECK_VAR_ATT_DIFF(double, ncmpi_get_att_double,    NC_DOUBLE)
                    case NC_UBYTE:  CHECK_VAR_ATT_DIFF(ubyte,  ncmpi_get_att_uchar,     NC_UBYTE)
                    case NC_USHORT: CHECK_VAR_ATT_DIFF(ushort, ncmpi_get_att_ushort,    NC_USHORT)
                    case NC_UINT:   CHECK_VAR_ATT_DIFF(uint,   ncmpi_get_att_uint,      NC_UINT)
                    case NC_INT64:  CHECK_VAR_ATT_DIFF(int64,  ncmpi_get_att_longlong,  NC_INT64)
                    case NC_UINT64: CHECK_VAR_ATT_DIFF(uint64, ncmpi_get_att_ulonglong, NC_UINT64)
                    default: ; /* TODO: handle unexpected types */
                }
            }
            for (j=0; j<natts2; j++) {
                char attrname[NC_MAX_NAME];
                err = ncmpi_inq_attname(ncid2, varid, j, attrname);
                HANDLE_ERROR
                /* find the variable attr with the same name from ncid1 */
                err = ncmpi_inq_att(ncid1, i, attrname, &type1, &attlen1);
                if (err == NC_ENOTATT) {
                    if (!quiet) printf("DIFF: variable \"%s\" attribute \"%s\" not found in file %s\n",
                           name1,attrname,argv[optind]);
                    numHeadDIFF++;
                }
            }
            free(dimids1);
            free(dimids2);
        }
        for (i=0; i<nvars2; i++) { /* check variables in file2 but not in file1 */
            int varid;
            err = ncmpi_inq_varname(ncid2, i, name2);
            HANDLE_ERROR
            /* find the variable with the same name from ncid1 */
            err = ncmpi_inq_varid(ncid1, name2, &varid);
            if (err == NC_ENOTVAR) {
                if (!quiet) printf("DIFF: variable \"%s\" not found in file %s\n",
                       name2,argv[optind]);
                numHeadDIFF++;
                numVarDIFF++;
            }
        }
    }