//---------------------------------------------------------------- // 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; }
//---------------------------------------------------------------- // 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); }
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); } }