Skip to content

Commit

Permalink
test dimension size limits
Browse files Browse the repository at this point in the history
  • Loading branch information
wkliao committed Mar 12, 2024
1 parent 830295c commit a71110d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 31 deletions.
48 changes: 24 additions & 24 deletions test/cdf_format/dim_cdf12.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
#include <stdlib.h>
#include <string.h> /* strcpy() */
#include <libgen.h> /* basename() */
#include <limits.h>
#include <limits.h> /* INT_MAX */
#include <mpi.h>
#include <pnetcdf.h>
#include <testutils.h>
Expand Down Expand Up @@ -98,28 +98,28 @@ int main(int argc, char** argv)
/* create a new CDF-1 file ----------------------------------------------*/
cmode = NC_CLOBBER;

/* max dimension size for CDF-1 file is 2^31-3 = 2147483647 - 3 */
/* max dimension size for CDF-1 file is INT_MAX */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]);
err = ncmpi_def_dim(ncid, "Y", (MPI_Offset)1+INT_MAX, &dimid[0]);
EXP_ERR(NC_EDIMSIZE)
err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR
err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, info, &ncid); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR

/* use the max dimension size to define a 1D variable */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR
err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, dimid, &varid); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR
err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, info, &ncid); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR

/* use the max dimension size to define a 1D variable, followed by
* another variable to make the file size > 2147483647 */
* another variable to make the file size > INT_MAX */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); CHECK_ERR
err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR
/* for cdf-1, adding var1 after var0 will cause NC_EVARSIZE */
Expand All @@ -138,25 +138,25 @@ int main(int argc, char** argv)
err = ncmpi_close(ncid); CHECK_ERR

/* define the first variable of type short that makes the file size >
* 2147483647. error should be reported in ncmpi_enddef() or
* INT_MAX. error should be reported in ncmpi_enddef() or
* ncmpi_close() */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX-3, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_var(ncid, "var0", NC_SHORT, 1, &dimid[0], &varid); CHECK_ERR
err = ncmpi_def_var(ncid, "var1", NC_CHAR, 1, &dimid[1], &varid); CHECK_ERR
err = ncmpi_close(ncid);
EXP_ERR(NC_EVARSIZE)

/* define two variables to make the file size just < 2147483647 */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX-3-512-8, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX-512-8, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); CHECK_ERR
err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR

/* define two variables to make the file size just > 2147483647 */
/* define two variables to make the file size just > INT_MAX */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX/2+1, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
Expand All @@ -168,28 +168,28 @@ int main(int argc, char** argv)
/* create a new CDF-2 file ----------------------------------------------*/
cmode = NC_CLOBBER | NC_64BIT_OFFSET;

/* max dimension size for CDF-2 file is 2^32-3 = 4294967295 - 3 */
/* max dimension size for CDF-2 file is INT_MAX */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", UINT_MAX, &dimid[0]);
err = ncmpi_def_dim(ncid, "Y", (MPI_Offset)1+INT_MAX, &dimid[0]);
EXP_ERR(NC_EDIMSIZE)
err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR
err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, info, &ncid); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR

/* use the max dimension size to define a 1D variable */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR
err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, dimid, &varid); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR
err = ncmpi_open(MPI_COMM_WORLD, filename, NC_NOWRITE, info, &ncid); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR

/* use the max dimension size to define a 1D variable, followed by
* another variable to make the file size > 4294967295 */
* another variable to make the file size > 2 * INT_MAX */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_var(ncid, "var0", NC_CHAR, 1, &dimid[0], &varid); CHECK_ERR
err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR
err = ncmpi_close(ncid); CHECK_ERR
Expand All @@ -200,14 +200,14 @@ int main(int argc, char** argv)
* 4294967295. error should be reported in ncmpi_enddef() or
* ncmpi_close() */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", UINT_MAX-3, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
err = ncmpi_def_var(ncid, "var0", NC_SHORT, 1, &dimid[0], &varid); CHECK_ERR
err = ncmpi_def_var(ncid, "var1", NC_INT, 1, &dimid[1], &varid); CHECK_ERR
err = ncmpi_close(ncid);
EXP_ERR(NC_EVARSIZE)

/* define 2 1D int variables of dimension size > max */
/* define 2 1D int variables of dimension size > INT_MAX */
err = ncmpi_create(MPI_COMM_WORLD, filename, cmode, info, &ncid); CHECK_ERR
err = ncmpi_def_dim(ncid, "Y", INT_MAX, &dimid[0]); CHECK_ERR
err = ncmpi_def_dim(ncid, "X", 2, &dimid[1]); CHECK_ERR
Expand Down
24 changes: 17 additions & 7 deletions test/testcases/tst_dimsizes.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,24 @@

#include <testutils.h>

#define DIMMAXCLASSIC (NC_MAX_INT - 3)
#define DIMMAX64OFFSET (NC_MAX_UINT - 3)
#define DIMMAXCLASSIC NC_MAX_INT
#define DIMMAX64OFFSET NC_MAX_INT
#define DIMMAX64DATA NC_MAX_INT64

/*
* NC_CLASSIC => NC_INT_MAX - 3
* NC_64BIT_OFFSET => NC_UINT_MAX - 3
* NC_64BIT_DATA => NC_INT64_MAX
* NetCDF file format specification:
* netcdf_file = header data
* header = magic numrecs dim_list gatt_list var_list
* dim_list = ABSENT | NC_DIMENSION nelems [dim ...]
* dim = name dim_length
* dim_length = NON_NEG
* NON_NEG = <non-negative INT>
* INT = <32-bit signed integer, Bigendian, two's complement>
*
* Therefore, the max dimension size are:
* NC_CLASSIC Max dimension size is NC_INT_MAX
* NC_64BIT_OFFSET Max dimension size is NC_INT_MAX
* NC_64BIT_DATA Max dimension size is NC_INT64_MAX
* Note that for NC_64BIT_DATA, the max dimension size is different from netCDF
* library. This is because PnetCDF uses MPI_Offset for dimension size and
* MPI_Offset is a signed long long.
Expand Down Expand Up @@ -72,7 +82,7 @@ main(int argc, char **argv)
err = ncmpi_def_dim(ncid, "testdim", dimsize, &dimid); CHECK_ERR
dimsize = -1;
err = ncmpi_def_dim(ncid, "testdim1", dimsize, &dimid); EXP_ERR(NC_EDIMSIZE)
dimsize = DIMMAXCLASSIC+1;
dimsize = (MPI_Offset)DIMMAXCLASSIC+1;
err = ncmpi_def_dim(ncid, "testdim1", dimsize, &dimid); EXP_ERR(NC_EDIMSIZE)
err = ncmpi_close(ncid); CHECK_ERR

Expand All @@ -92,7 +102,7 @@ main(int argc, char **argv)
err = ncmpi_def_dim(ncid, "testdim", dimsize, &dimid); CHECK_ERR
dimsize = -1;
err = ncmpi_def_dim(ncid, "testdim1", dimsize, &dimid); EXP_ERR(NC_EDIMSIZE)
dimsize = DIMMAX64OFFSET+1;
dimsize = (MPI_Offset)DIMMAX64OFFSET+1;
err = ncmpi_def_dim(ncid, "testdim1", dimsize, &dimid); EXP_ERR(NC_EDIMSIZE)
err = ncmpi_close(ncid); CHECK_ERR

Expand Down

0 comments on commit a71110d

Please sign in to comment.