/** * Test the darray functionality. Create a netCDF file with 3 * dimensions and 3 variable, and use PIOc_write_darray_multi() to * write one record of data to all three vars at once. * * @param iosysid the IO system ID. * @param ioid the ID of the decomposition. * @param num_flavors the number of IOTYPES available in this build. * @param flavor array of available iotypes. * @param my_rank rank of this task. * @param pio_type the type of the data. * @returns 0 for success, error code otherwise. */ int test_darray(int iosysid, int ioid, int num_flavors, int *flavor, int my_rank, int pio_type) { #define NUM_TEST_CASES_WRT_MULTI 2 #define NUM_TEST_CASES_FILLVALUE 2 char filename[PIO_MAX_NAME + 1]; /* Name for the output files. */ int dimids[NDIM]; /* The dimension IDs. */ int ncid; /* The ncid of the netCDF file. */ int ncid2; /* The ncid of the re-opened netCDF file. */ int varid[NVAR]; /* The IDs of the netCDF varables. */ int other_varid; /* The IDs of a var of different type. */ int wrong_varid[NVAR]; /* These will not work. */ PIO_Offset arraylen = 4; /* Amount of data from each task. */ void *fillvalue; /* Pointer to fill value. */ void *test_data; /* Pointer to test data we will write. */ void *test_data_in; /* Pointer to buffer we will read into. */ int ret; /* Return code. */ /* Default fill value array for each type. */ signed char byte_fill[NVAR] = {NC_FILL_BYTE, NC_FILL_BYTE, NC_FILL_BYTE}; char char_fill[NVAR] = {NC_FILL_CHAR, NC_FILL_CHAR, NC_FILL_CHAR}; short short_fill[NVAR] = {NC_FILL_SHORT, NC_FILL_SHORT, NC_FILL_SHORT}; int int_fill[NVAR] = {NC_FILL_INT, NC_FILL_INT, NC_FILL_INT}; float float_fill[NVAR] = {NC_FILL_FLOAT, NC_FILL_FLOAT, NC_FILL_FLOAT}; double double_fill[NVAR] = {NC_FILL_DOUBLE, NC_FILL_DOUBLE, NC_FILL_DOUBLE}; #ifdef _NETCDF4 unsigned char ubyte_fill[NVAR] = {NC_FILL_UBYTE, NC_FILL_UBYTE, NC_FILL_UBYTE}; unsigned short ushort_fill[NVAR] = {NC_FILL_USHORT, NC_FILL_USHORT, NC_FILL_USHORT}; unsigned int uint_fill[NVAR] = {NC_FILL_UINT, NC_FILL_UINT, NC_FILL_UINT}; long long int64_fill[NVAR] = {NC_FILL_INT64, NC_FILL_INT64, NC_FILL_INT64}; unsigned long long uint64_fill[NVAR] = {NC_FILL_UINT64, NC_FILL_UINT64, NC_FILL_UINT64}; #endif /* _NETCDF4 */ /* Test data we will write. */ signed char test_data_byte[arraylen * NVAR]; char test_data_char[arraylen * NVAR]; short test_data_short[arraylen * NVAR]; int test_data_int[arraylen * NVAR]; float test_data_float[arraylen * NVAR]; double test_data_double[arraylen * NVAR]; #ifdef _NETCDF4 unsigned char test_data_ubyte[arraylen * NVAR]; unsigned short test_data_ushort[arraylen * NVAR]; unsigned int test_data_uint[arraylen * NVAR]; long long test_data_int64[arraylen * NVAR]; unsigned long long test_data_uint64[arraylen * NVAR]; #endif /* _NETCDF4 */ /* We will read test data into these buffers. */ signed char test_data_byte_in[arraylen]; char test_data_char_in[arraylen]; short test_data_short_in[arraylen]; int test_data_int_in[arraylen]; float test_data_float_in[arraylen]; double test_data_double_in[arraylen]; #ifdef _NETCDF4 unsigned char test_data_ubyte_in[arraylen]; unsigned short test_data_ushort_in[arraylen]; unsigned int test_data_uint_in[arraylen]; long long test_data_int64_in[arraylen]; unsigned long long test_data_uint64_in[arraylen]; #endif /* _NETCDF4 */ /* Initialize a big blob of test data for NVAR vars. */ for (int f = 0; f < arraylen * NVAR; f++) { test_data_byte[f] = my_rank * 1 + f; test_data_char[f] = my_rank * 2 + f; test_data_short[f] = my_rank * 5 + f; test_data_int[f] = my_rank * 10 + f; test_data_float[f] = my_rank * 10 + f + 0.5; test_data_double[f] = my_rank * 100000 + f + 0.5; #ifdef _NETCDF4 test_data_ubyte[f] = my_rank * 3 + f; test_data_ushort[f] = my_rank * 9 + f; test_data_uint[f] = my_rank * 100 + f; test_data_int64[f] = my_rank * 10000 + f; test_data_uint64[f] = my_rank * 100000 + f; #endif /* _NETCDF4 */ } /* Use PIO to create the example file in each of the four * available ways. */ for (int fmt = 0; fmt < num_flavors; fmt++) { /* 1-byte types not working with pnetcdf. */ if (flavor[fmt] == PIO_IOTYPE_PNETCDF && (pio_type == PIO_BYTE || pio_type == PIO_CHAR)) continue; /* NetCDF-4 types only work with netCDF-4. */ if (pio_type > PIO_DOUBLE && (flavor[fmt] != PIO_IOTYPE_NETCDF4C && flavor[fmt] != PIO_IOTYPE_NETCDF4P)) continue; /* Add a couple of extra tests for the * PIOc_write_darray_multi() function. */ for (int test_multi = 0; test_multi < NUM_TEST_CASES_WRT_MULTI; test_multi++) { /* Test with/without providing a fill value to PIOc_write_darray(). */ for (int provide_fill = 0; provide_fill < NUM_TEST_CASES_FILLVALUE; provide_fill++) { /* Create the filename. */ sprintf(filename, "data_%s_iotype_%d_pio_type_%d_test_multi_%d_provide_fill_%d.nc", TEST_NAME, flavor[fmt], pio_type, test_multi, provide_fill); /* Select the fill value and data. */ switch (pio_type) { case PIO_BYTE: fillvalue = provide_fill ? byte_fill : NULL; test_data = test_data_byte; test_data_in = test_data_byte_in; break; case PIO_CHAR: fillvalue = provide_fill ? char_fill : NULL; test_data = test_data_char; test_data_in = test_data_char_in; break; case PIO_SHORT: fillvalue = provide_fill ? short_fill : NULL; test_data = test_data_short; test_data_in = test_data_short_in; break; case PIO_INT: fillvalue = provide_fill ? int_fill : NULL; test_data = test_data_int; test_data_in = test_data_int_in; break; case PIO_FLOAT: fillvalue = provide_fill ? float_fill : NULL; test_data = test_data_float; test_data_in = test_data_float_in; break; case PIO_DOUBLE: fillvalue = provide_fill ? double_fill : NULL; test_data = test_data_double; test_data_in = test_data_double_in; break; #ifdef _NETCDF4 case PIO_UBYTE: fillvalue = provide_fill ? ubyte_fill : NULL; test_data = test_data_ubyte; test_data_in = test_data_ubyte_in; break; case PIO_USHORT: fillvalue = provide_fill ? ushort_fill : NULL; test_data = test_data_ushort; test_data_in = test_data_ushort_in; break; case PIO_UINT: fillvalue = provide_fill ? uint_fill : NULL; test_data = test_data_uint; test_data_in = test_data_uint_in; break; case PIO_INT64: fillvalue = provide_fill ? int64_fill : NULL; test_data = test_data_int64; test_data_in = test_data_int64_in; break; case PIO_UINT64: fillvalue = provide_fill ? uint64_fill : NULL; test_data = test_data_uint64; test_data_in = test_data_uint64_in; break; #endif /* _NETCDF4 */ default: ERR(ERR_WRONG); } /* Create the netCDF output file. */ if ((ret = PIOc_createfile(iosysid, &ncid, &flavor[fmt], filename, PIO_CLOBBER))) ERR(ret); /* Define netCDF dimensions and variable. */ for (int d = 0; d < NDIM; d++) if ((ret = PIOc_def_dim(ncid, dim_name[d], (PIO_Offset)dim_len[d], &dimids[d]))) ERR(ret); /* Define a variable. */ for (int v = 0; v < NVAR; v++) if ((ret = PIOc_def_var(ncid, var_name[v], pio_type, NDIM, dimids, &varid[v]))) ERR(ret); /* Define a variable of a different type, to test error handling. */ int other_pio_type = pio_type < 5 ? pio_type + 1 : PIO_INT; if ((ret = PIOc_def_var(ncid, "OTHER_VAR", other_pio_type, NDIM, dimids, &other_varid))) ERR(ret); /* Leave a note. */ if ((ret = PIOc_put_att_text(ncid, NC_GLOBAL, NOTE_NAME, strlen(NOTE), NOTE))) ERR(ret); int num_stooges = TOTAL_NUMBER_OF_STOOGES; if ((ret = PIOc_put_att_int(ncid, NC_GLOBAL, TOTAL_NUMBER_OF_STOOGES_NAME, PIO_INT, 1, &num_stooges))) ERR(ret); /* End define mode. */ if ((ret = PIOc_enddef(ncid))) ERR(ret); /* Set the value of the record dimension. */ if ((ret = PIOc_setframe(ncid, varid[0], 0))) ERR(ret); int frame[NVAR] = {0, 0, 0}; int flushtodisk = test_multi; /* This will not work, because we mix var types. */ wrong_varid[0] = varid[0]; wrong_varid[1] = varid[1]; wrong_varid[0] = other_varid; // if (PIOc_write_darray_multi(ncid, wrong_varid, ioid, NVAR, arraylen, test_data, frame, // fillvalue, flushtodisk) != PIO_EINVAL) // ERR(ERR_WRONG); /* Write the data with the _multi function. */ if ((ret = PIOc_write_darray_multi(ncid, varid, ioid, NVAR, arraylen, test_data, frame, fillvalue, flushtodisk))) ERR(ret); /* Close the netCDF file. */ if ((ret = PIOc_closefile(ncid))) ERR(ret); /* Reopen the file. */ if ((ret = PIOc_openfile(iosysid, &ncid2, &flavor[fmt], filename, PIO_NOWRITE))) ERR(ret); /* Now use read_darray on each var in turn and make * sure we get correct data. */ for (int v = 0; v < NVAR; v++) { /* Set the value of the record dimension. */ if ((ret = PIOc_setframe(ncid2, varid[v], 0))) ERR(ret); /* Read the data. */ if ((ret = PIOc_read_darray(ncid2, varid[v], ioid, arraylen, test_data_in))) ERR(ret); /* Check the results. */ for (int f = 0; f < arraylen; f++) { switch (pio_type) { case PIO_BYTE: if (test_data_byte_in[f] != test_data_byte[f + arraylen * v]) return ERR_WRONG; break; case PIO_CHAR: if (test_data_char_in[f] != test_data_char[f + arraylen * v]) return ERR_WRONG; break; case PIO_SHORT: if (test_data_short_in[f] != test_data_short[f + arraylen * v]) return ERR_WRONG; break; case PIO_INT: if (test_data_int_in[f] != test_data_int[f + arraylen * v]) return ERR_WRONG; break; case PIO_FLOAT: if (test_data_float_in[f] != test_data_float[f + arraylen * v]) return ERR_WRONG; break; case PIO_DOUBLE: if (test_data_double_in[f] != test_data_double[f + arraylen * v]) return ERR_WRONG; break; #ifdef _NETCDF4 case PIO_UBYTE: if (test_data_ubyte_in[f] != test_data_ubyte[f + arraylen * v]) return ERR_WRONG; break; case PIO_USHORT: if (test_data_ushort_in[f] != test_data_ushort[f + arraylen * v]) return ERR_WRONG; break; case PIO_UINT: if (test_data_uint_in[f] != test_data_uint[f + arraylen * v]) return ERR_WRONG; break; case PIO_INT64: if (test_data_int64_in[f] != test_data_int64[f + arraylen * v]) return ERR_WRONG; break; case PIO_UINT64: if (test_data_uint64_in[f] != test_data_uint64[f + arraylen * v]) return ERR_WRONG; break; #endif /* _NETCDF4 */ default: ERR(ERR_WRONG); } } } /* Close the netCDF file. */ if ((ret = PIOc_closefile(ncid2))) ERR(ret); } /* next fillvalue test case */ } /* next test multi */ } /* next iotype */ return PIO_NOERR; }
/** Run Tests for NetCDF-4 Functions. * * @param argc argument count * @param argv array of arguments */ int main(int argc, char **argv) { int verbose = 1; /** Zero-based rank of processor. */ int my_rank; /** Number of processors involved in current execution. */ int ntasks; /** Specifies the flavor of netCDF output format. */ int iotype; /** Different output flavors. */ int format[NUM_NETCDF_FLAVORS] = {PIO_IOTYPE_PNETCDF, PIO_IOTYPE_NETCDF, PIO_IOTYPE_NETCDF4C, PIO_IOTYPE_NETCDF4P}; /** Names for the output files. */ char filename[NUM_NETCDF_FLAVORS][NC_MAX_NAME + 1] = {"test_names_pnetcdf.nc", "test_names_classic.nc", "test_names_serial4.nc", "test_names_parallel4.nc"}; /** Number of processors that will do IO. In this test we * will do IO from all processors. */ int niotasks; /** Stride in the mpi rank between io tasks. Always 1 in this * test. */ int ioproc_stride = 1; /** Number of the aggregator? Always 0 in this test. */ int numAggregator = 0; /** Zero based rank of first processor to be used for I/O. */ int ioproc_start = 0; /** The dimension IDs. */ int dimids[NDIM]; /** Array index per processing unit. */ PIO_Offset elements_per_pe; /** The ID for the parallel I/O system. */ int iosysid; /** The ncid of the netCDF file. */ int ncid = 0; /** The ID of the netCDF varable. */ int varid; /** Storage of netCDF-4 files (contiguous vs. chunked). */ int storage; /** Chunksizes set in the file. */ size_t my_chunksize[NDIM]; /** The shuffle filter setting in the netCDF-4 test file. */ int shuffle; /** Non-zero if deflate set for the variable in the netCDF-4 test file. */ int deflate; /** The deflate level set for the variable in the netCDF-4 test file. */ int deflate_level; /** Non-zero if fletcher32 filter is used for variable. */ int fletcher32; /** Endianness of variable. */ int endianness; /* Size of the file chunk cache. */ size_t chunk_cache_size; /* Number of elements in file cache. */ size_t nelems; /* File cache preemption. */ float preemption; /* Size of the var chunk cache. */ size_t var_cache_size; /* Number of elements in var cache. */ size_t var_cache_nelems; /* Var cache preemption. */ float var_cache_preemption; /** The I/O description ID. */ int ioid; /** A buffer for sample data. */ float *buffer; /** A buffer for reading data back from the file. */ int *read_buffer; /** The decomposition mapping. */ PIO_Offset *compdof; /** Return code. */ int ret; /** Index for loops. */ int fmt, d, d1, i; #ifdef TIMING /* Initialize the GPTL timing library. */ if ((ret = GPTLinitialize ())) return ret; #endif /* Initialize MPI. */ if ((ret = MPI_Init(&argc, &argv))) MPIERR(ret); /* Learn my rank and the total number of processors. */ if ((ret = MPI_Comm_rank(MPI_COMM_WORLD, &my_rank))) MPIERR(ret); if ((ret = MPI_Comm_size(MPI_COMM_WORLD, &ntasks))) MPIERR(ret); /* Check that a valid number of processors was specified. */ if (!(ntasks == 1 || ntasks == 2 || ntasks == 4 || ntasks == 8 || ntasks == 16)) fprintf(stderr, "Number of processors must be 1, 2, 4, 8, or 16!\n"); if (verbose) printf("%d: ParallelIO Library example1 running on %d processors.\n", my_rank, ntasks); /* keep things simple - 1 iotask per MPI process */ niotasks = ntasks; /* Initialize the PIO IO system. This specifies how * many and which processors are involved in I/O. */ if ((ret = PIOc_Init_Intracomm(MPI_COMM_WORLD, niotasks, ioproc_stride, ioproc_start, PIO_REARR_SUBSET, &iosysid))) ERR(ret); /* Describe the decomposition. This is a 1-based array, so add 1! */ elements_per_pe = X_DIM_LEN * Y_DIM_LEN / ntasks; if (!(compdof = malloc(elements_per_pe * sizeof(PIO_Offset)))) return PIO_ENOMEM; for (i = 0; i < elements_per_pe; i++) { compdof[i] = my_rank * elements_per_pe + i + 1; } /* Create the PIO decomposition for this test. */ if (verbose) printf("rank: %d Creating decomposition...\n", my_rank); if ((ret = PIOc_InitDecomp(iosysid, PIO_FLOAT, 2, &dim_len[1], (PIO_Offset)elements_per_pe, compdof, &ioid, NULL, NULL, NULL))) ERR(ret); free(compdof); /* How many flavors will we be running for? */ int num_flavors = 0; int fmtidx = 0; #ifdef _PNETCDF num_flavors++; format[fmtidx++] = PIO_IOTYPE_PNETCDF; #endif #ifdef _NETCDF num_flavors++; format[fmtidx++] = PIO_IOTYPE_NETCDF; #endif #ifdef _NETCDF4 num_flavors += 2; format[fmtidx++] = PIO_IOTYPE_NETCDF4C; format[fmtidx] = PIO_IOTYPE_NETCDF4P; #endif /* Use PIO to create the example file in each of the four * available ways. */ for (fmt = 0; fmt < num_flavors; fmt++) { /* Create the netCDF output file. */ if (verbose) printf("rank: %d Creating sample file %s with format %d...\n", my_rank, filename[fmt], format[fmt]); if ((ret = PIOc_createfile(iosysid, &ncid, &(format[fmt]), filename[fmt], PIO_CLOBBER))) ERR(ret); /* Define netCDF dimensions and variable. */ if (verbose) printf("rank: %d Defining netCDF metadata...\n", my_rank); for (d = 0; d < NDIM; d++) { if (verbose) printf("rank: %d Defining netCDF dimension %s, length %d\n", my_rank, dim_name[d], dim_len[d]); if ((ret = PIOc_def_dim(ncid, dim_name[d], (PIO_Offset)dim_len[d], &dimids[d]))) ERR(ret); } /* Check the dimension names. */ if ((ret = check_dim_names(my_rank, ncid, verbose))) ERR(ret); /* Define a global attribute. */ int att_val = 42; if ((ret = PIOc_put_att_int(ncid, NC_GLOBAL, ATT_NAME, NC_INT, 1, &att_val))) ERR(ret); /* Check the attribute name. */ if ((ret = check_att_name(my_rank, ncid, verbose))) ERR(ret); /* Define a variable. */ if ((ret = PIOc_def_var(ncid, VAR_NAME, PIO_FLOAT, NDIM, dimids, &varid))) ERR(ret); /* Check the variable name. */ if ((ret = check_var_name(my_rank, ncid, verbose))) ERR(ret); if ((ret = PIOc_enddef(ncid))) ERR(ret); /* Close the netCDF file. */ if (verbose) printf("rank: %d Closing the sample data file...\n", my_rank); if ((ret = PIOc_closefile(ncid))) ERR(ret); /* Put a barrier here to make verbose output look better. */ if ((ret = MPI_Barrier(MPI_COMM_WORLD))) MPIERR(ret); } /* Free the PIO decomposition. */ if (verbose) printf("rank: %d Freeing PIO decomposition...\n", my_rank); if ((ret = PIOc_freedecomp(iosysid, ioid))) ERR(ret); /* Finalize the IO system. */ if (verbose) printf("rank: %d Freeing PIO resources...\n", my_rank); if ((ret = PIOc_finalize(iosysid))) ERR(ret); /* Finalize the MPI library. */ MPI_Finalize(); #ifdef TIMING /* Finalize the GPTL timing library. */ if ((ret = GPTLfinalize ())) return ret; #endif return 0; }
/* Run Tests for Init_Intercomm. */ int main(int argc, char **argv) { /* Zero-based rank of processor. */ int my_rank; /* Number of processors involved in current execution. */ int ntasks; int num_flavors; /* Number of PIO netCDF flavors in this build. */ int flavor[NUM_FLAVORS]; /* iotypes for the supported netCDF IO flavors. */ /* Names for the output files. */ char filename[NUM_FLAVORS][NC_MAX_NAME + 1]; /* The ID for the parallel I/O system. */ int iosysid[COMPONENT_COUNT]; /* Return code. */ int ret; MPI_Comm test_comm; char too_long_name[PIO_MAX_NAME * 5 + 1]; /* Create a name that is too long. */ memset(too_long_name, 74, PIO_MAX_NAME * 5); too_long_name[PIO_MAX_NAME * 5] = 0; /* Set up test. */ if ((ret = pio_test_init2(argc, argv, &my_rank, &ntasks, TARGET_NTASKS, TARGET_NTASKS, -1, &test_comm))) ERR(ERR_INIT); /* Figure out iotypes. */ if ((ret = get_iotypes(&num_flavors, flavor))) ERR(ret); if (my_rank < TARGET_NTASKS) { /* How many processors will be used for our IO and 2 computation components. */ int num_procs[COMPONENT_COUNT] = {2}; /* Is the current process a computation task? */ int comp_task = my_rank < 2 ? 0 : 1; /* Index of computation task in iosysid array. Varies by rank and * does not apply to IO component processes. */ int my_comp_idx = comp_task ? 0 : -1; /* Initialize the IO system. */ if ((ret = PIOc_init_async(test_comm, NUM_IO_PROCS, NULL, COMPONENT_COUNT, num_procs, NULL, NULL, NULL, PIO_REARR_BOX, iosysid))) ERR(ERR_AWFUL); /* All the netCDF calls are only executed on the computation * tasks. The IO tasks have not returned from PIOc_Init_Intercomm, * and when the do, they should go straight to finalize. */ if (comp_task) { for (int fmt = 0; fmt < num_flavors; fmt++) { int ncid, varid, dimid; PIO_Offset start[NDIM], count[NDIM] = {0}; int data[DIM_LEN]; /* Create the filename for this flavor. */ sprintf(filename[fmt], "test_intercomm2_%d.nc", flavor[fmt]); /* Create a netCDF file with one dimension and one variable. */ if ((ret = PIOc_createfile(iosysid[my_comp_idx], &ncid, &flavor[fmt], filename[fmt], NC_CLOBBER))) ERR(ret); /* End define mode, then re-enter it. */ if ((ret = PIOc_enddef(ncid))) ERR(ret); if ((ret = PIOc_redef(ncid))) ERR(ret); /* Test the inq_format function. */ int myformat; if (PIOc_inq_format(ncid + TEST_VAL_42, &myformat) != PIO_EBADID) ERR(ERR_WRONG); if ((ret = PIOc_inq_format(ncid, &myformat))) ERR(ret); if ((flavor[fmt] == PIO_IOTYPE_PNETCDF || flavor[fmt] == PIO_IOTYPE_NETCDF) && myformat != 1) ERR(ERR_AWFUL); else if ((flavor[fmt] == PIO_IOTYPE_NETCDF4C || flavor[fmt] == PIO_IOTYPE_NETCDF4P) && myformat != 3) ERR(ERR_AWFUL); /* Test the inq_type function for atomic types. */ char type_name[NC_MAX_NAME + 1]; PIO_Offset type_size; nc_type xtype[NUM_TYPES] = {NC_CHAR, NC_BYTE, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE, NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64, NC_UINT64}; int type_len[NUM_TYPES] = {1, 1, 2, 4, 4, 8, 1, 2, 4, 8, 8}; int max_type = flavor[fmt] == PIO_IOTYPE_NETCDF ? NC_DOUBLE : NC_UINT64; /* This should not work. */ if (PIOc_inq_type(ncid + TEST_VAL_42, xtype[0], type_name, &type_size) != PIO_EBADID) ERR(ERR_WRONG); /* These should work. */ for (int i = 0; i < max_type; i++) { if ((ret = PIOc_inq_type(ncid, xtype[i], type_name, &type_size))) ERR(ret); if (type_size != type_len[i]) ERR(ERR_AWFUL); } /* Define a dimension. */ char dimname2[NC_MAX_NAME + 1]; if ((ret = PIOc_def_dim(ncid, FIRST_DIM_NAME, DIM_LEN, &dimid))) ERR(ret); if ((ret = PIOc_inq_dimname(ncid, 0, dimname2))) ERR(ret); if (strcmp(dimname2, FIRST_DIM_NAME)) ERR(ERR_WRONG); if ((ret = PIOc_rename_dim(ncid, 0, DIM_NAME))) ERR(ret); /* These should not work. */ if (PIOc_rename_dim(ncid + TEST_VAL_42, 0, DIM_NAME) != PIO_EBADID) ERR(ERR_WRONG); if (PIOc_rename_dim(ncid, 0, NULL) != PIO_EINVAL) ERR(ERR_WRONG); if (PIOc_rename_dim(ncid, 0, too_long_name) != PIO_EINVAL) ERR(ERR_WRONG); /* Define a 1-D variable. */ char varname2[NC_MAX_NAME + 1]; if ((ret = PIOc_def_var(ncid, FIRST_VAR_NAME, NC_INT, NDIM, &dimid, &varid))) ERR(ret); if ((ret = PIOc_inq_varname(ncid, 0, varname2))) ERR(ret); if (strcmp(varname2, FIRST_VAR_NAME)) ERR(ERR_WRONG); if ((ret = PIOc_rename_var(ncid, 0, VAR_NAME))) ERR(ret); /* These should not work. */ if (PIOc_rename_var(ncid + TEST_VAL_42, 0, VAR_NAME) != PIO_EBADID) ERR(ERR_WRONG); if (PIOc_rename_var(ncid, 0, NULL) != PIO_EINVAL) ERR(ERR_WRONG); if (PIOc_rename_var(ncid, 0, too_long_name) != PIO_EINVAL) ERR(ERR_WRONG); /* Add a global attribute. */ int att_data = ATT_VALUE; short short_att_data = ATT_VALUE; float float_att_data = ATT_VALUE; double double_att_data = ATT_VALUE; char attname2[NC_MAX_NAME + 1]; /* Write an att and rename it. */ if ((ret = PIOc_put_att_int(ncid, NC_GLOBAL, FIRST_ATT_NAME, NC_INT, 1, &att_data))) ERR(ret); if ((ret = PIOc_inq_attname(ncid, NC_GLOBAL, 0, attname2))) ERR(ret); if (strcmp(attname2, FIRST_ATT_NAME)) ERR(ERR_WRONG); if ((ret = PIOc_rename_att(ncid, NC_GLOBAL, FIRST_ATT_NAME, ATT_NAME))) ERR(ret); /* These should not work. */ if (PIOc_inq_attname(ncid + TEST_VAL_42, NC_GLOBAL, 0, attname2) != PIO_EBADID) ERR(ERR_WRONG); if (PIOc_rename_att(ncid + TEST_VAL_42, NC_GLOBAL, FIRST_ATT_NAME, ATT_NAME) != PIO_EBADID) ERR(ERR_WRONG); if (PIOc_rename_att(ncid, NC_GLOBAL, FIRST_ATT_NAME, NULL) != PIO_EINVAL) ERR(ERR_WRONG); if (PIOc_rename_att(ncid, NC_GLOBAL, FIRST_ATT_NAME, too_long_name) != PIO_EINVAL) ERR(ERR_WRONG); if (PIOc_del_att(ncid + TEST_VAL_42, NC_GLOBAL, FIRST_ATT_NAME) != PIO_EBADID) ERR(ERR_WRONG); if (PIOc_del_att(ncid, NC_GLOBAL, NULL) != PIO_EINVAL) ERR(ERR_WRONG); if (PIOc_del_att(ncid, NC_GLOBAL, too_long_name) != PIO_EINVAL) ERR(ERR_WRONG); /* Write an att and delete it. */ if ((ret = PIOc_put_att_int(ncid, NC_GLOBAL, FIRST_ATT_NAME, NC_INT, 1, &att_data))) ERR(ret); if ((ret = PIOc_del_att(ncid, NC_GLOBAL, FIRST_ATT_NAME))) ERR(ret); /* if ((ret = PIOc_inq_att(ncid, NC_GLOBAL, FIRST_ATT_NAME, NULL, NULL)) != PIO_ENOTATT) */ /* { */ /* printf("ret = %d\n", ret); */ /* ERR(ERR_AWFUL); */ /* } */ /* Write some atts of different types. */ if ((ret = PIOc_put_att_short(ncid, NC_GLOBAL, SHORT_ATT_NAME, NC_SHORT, 1, &short_att_data))) ERR(ret); if ((ret = PIOc_put_att_float(ncid, NC_GLOBAL, FLOAT_ATT_NAME, NC_FLOAT, 1, &float_att_data))) ERR(ret); if ((ret = PIOc_put_att_double(ncid, NC_GLOBAL, DOUBLE_ATT_NAME, NC_DOUBLE, 1, &double_att_data))) ERR(ret); /* Check some att types. */ nc_type myatttype; if ((ret = PIOc_inq_atttype(ncid, NC_GLOBAL, SHORT_ATT_NAME, &myatttype))) ERR(ret); if (myatttype != NC_SHORT) ERR(ERR_WRONG); if ((ret = PIOc_inq_atttype(ncid, NC_GLOBAL, FLOAT_ATT_NAME, &myatttype))) ERR(ret); if (myatttype != NC_FLOAT) ERR(ERR_WRONG); if ((ret = PIOc_inq_atttype(ncid, NC_GLOBAL, DOUBLE_ATT_NAME, &myatttype))) ERR(ret); if (myatttype != NC_DOUBLE) ERR(ERR_WRONG); /* End define mode. */ if ((ret = PIOc_enddef(ncid))) ERR(ret); /* Write some data. For the PIOc_put/get functions, all * data must be on compmaster before the function is * called. Only compmaster's arguments are passed to the * async msg handler. All other computation tasks are * ignored. */ for (int i = 0; i < DIM_LEN; i++) data[i] = i; start[0] = 0; count[0] = DIM_LEN; if ((ret = PIOc_put_vars_tc(ncid, varid, start, count, NULL, NC_INT, data))) ERR(ret); /* Close the file. */ if ((ret = PIOc_closefile(ncid))) ERR(ret); /* Check the file for correctness. */ if ((ret = check_file(iosysid[my_comp_idx], flavor[fmt], filename[fmt], my_rank))) ERR(ret); /* Now delete the file. */ /* if ((ret = PIOc_deletefile(iosysid, filename[fmt]))) */ /* ERR(ret); */ /* if ((ret = PIOc_openfile(iosysid, &ncid, &flavor[fmt], filename[fmt], */ /* NC_NOWRITE)) != PIO_ENFILE) */ /* ERR(ERR_AWFUL); */ } /* next netcdf flavor */ /* Finalize the IO system. Only call this from the computation tasks. */ if ((ret = PIOc_finalize(iosysid[my_comp_idx]))) ERR(ret); } } /* my_rank < TARGET_NTASKS */ /* Finalize test. */ if ((ret = pio_test_finalize(&test_comm))) return ERR_AWFUL; printf("%d %s SUCCESS!!\n", my_rank, TEST_NAME); return 0; }