Skip to content

Commit

Permalink
Merge pull request ESMCI#1698 from NCAR/ejh_test_simple
Browse files Browse the repository at this point in the history
allow use of compression with netcdf-4 parallel, also add a simple test
  • Loading branch information
edwardhartnett authored Aug 6, 2020
2 parents eedc46c + ee339d0 commit a14b65b
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 47 deletions.
7 changes: 2 additions & 5 deletions src/clib/pio_nc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,8 @@ PIOc_def_var_deflate(int ncid, int varid, int shuffle, int deflate,
if (ios->ioproc)
{
#ifdef _NETCDF4
if (file->iotype == PIO_IOTYPE_NETCDF4P)
ierr = NC_EINVAL;
else
if (file->do_io)
ierr = nc_def_var_deflate(file->fh, varid, shuffle, deflate, deflate_level);
if (file->do_io)
ierr = nc_def_var_deflate(file->fh, varid, shuffle, deflate, deflate_level);
#endif
}

Expand Down
8 changes: 8 additions & 0 deletions tests/cunit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ if (NOT PIO_USE_MPISERIAL)
target_link_libraries (test_async_manyproc pioc)
add_executable (test_async_1d EXCLUDE_FROM_ALL test_async_1d.c)
target_link_libraries (test_async_1d pioc)
add_executable (test_simple EXCLUDE_FROM_ALL test_simple.c test_common.c)
target_link_libraries (test_simple pioc)
endif ()
endif ()
add_executable (test_spmd EXCLUDE_FROM_ALL test_spmd.c test_common.c)
Expand Down Expand Up @@ -146,6 +148,7 @@ if(PIO_USE_MALLOC)
add_dependencies (tests test_async_multi2)
add_dependencies (tests test_async_manyproc)
add_dependencies (tests test_async_1d)
add_dependencies (tests test_simple)
endif ()

# Test Timeout in seconds.
Expand All @@ -162,6 +165,7 @@ set (AT_LEAST_TWO_TASKS 3)
set (AT_LEAST_THREE_TASKS 4)
set (AT_LEAST_FOUR_TASKS 5)
set (AT_LEAST_EIGHT_TASKS 9)
set (EXACTLY_FOUR_TASKS 4)

if (PIO_USE_MPISERIAL)
add_test(NAME test_pioc
Expand Down Expand Up @@ -317,5 +321,9 @@ else ()
EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/test_decomps
NUMPROCS ${AT_LEAST_FOUR_TASKS}
TIMEOUT ${DEFAULT_TEST_TIMEOUT})
add_mpi_test(test_simple
EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/test_simple
NUMPROCS ${EXACTLY_FOUR_TASKS}
TIMEOUT ${DEFAULT_TEST_TIMEOUT})
endif ()
MESSAGE("CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS}")
3 changes: 2 additions & 1 deletion tests/cunit/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ test_decomp_uneven test_decomps test_rearr test_darray_async_simple \
test_darray_async test_darray_async_many test_darray_2sync \
test_async_multicomp test_async_multi2 test_async_manyproc \
test_darray_fill test_decomp_frame test_perf2 test_async_perf \
test_darray_vard test_async_1d test_darray_append
test_darray_vard test_async_1d test_darray_append test_simple

if RUN_TESTS
# Tests will run from a bash script.
Expand Down Expand Up @@ -66,6 +66,7 @@ test_perf2_SOURCES = test_perf2.c test_common.c pio_tests.h
test_async_perf_SOURCES = test_async_perf.c test_common.c pio_tests.h
test_darray_vard_SOURCES = test_darray_vard.c test_common.c pio_tests.h
test_async_1d_SOURCES = test_async_1d.c pio_tests.h
test_simple_SOURCES = test_simple.c test_common.c pio_tests.h

# Distribute the test script.
EXTRA_DIST = run_tests.sh CMakeLists.txt test_darray_frame.c
Expand Down
1 change: 1 addition & 0 deletions tests/cunit/pio_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void test_stop_mpe_log(int state, const char *msg);
#define ERR_WRONG 1112
#define ERR_GPTL 1113
#define ERR_MPI 1114
#define ERR_MEM 1115

/** The meaning of life, the universe, and everything. */
#define TEST_VAL_42 42
Expand Down
4 changes: 2 additions & 2 deletions tests/cunit/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ printf 'running PIO tests...\n'
# test_darray_multivar3
PIO_TESTS='test_intercomm2 test_async_mpi test_spmd test_rearr test_async_simple '\
'test_async_3proc test_async_4proc test_iosystem2_simple test_iosystem2_simple2 '\
'test_iosystem2 test_iosystem3_simple test_iosystem3_simple2 test_iosystem3 test_pioc '\
'test_iosystem2 test_iosystem3_simple test_iosystem3_simple2 test_iosystem3 test_simple test_pioc '\
'test_pioc_unlim test_pioc_putget test_pioc_fill test_darray test_darray_multi '\
'test_darray_multivar test_darray_multivar2 test_darray_1d '\
'test_darray_3d test_decomp_uneven test_decomps test_darray_async_simple '\
'test_darray_async test_darray_async_many test_darray_2sync test_async_multicomp '\
'test_darray_fill test_darray_vard test_async_1d test_darray_append'
'test_darray_fill test_darray_vard test_async_1d test_darray_append test_simple'

success1=true
success2=true
Expand Down
19 changes: 5 additions & 14 deletions tests/cunit/test_pioc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1570,18 +1570,9 @@ int test_nc4(int iosysid, int num_flavors, int *flavor, int my_rank)
if ((ret = PIOc_def_var_chunking(ncid, 0, NC_CHUNKED, chunksize)))
ERR(ret);

/* Setting deflate should not work with parallel iotype. */
ret = PIOc_def_var_deflate(ncid, 0, 0, 1, 1);
if (flavor[fmt] == PIO_IOTYPE_NETCDF4P)
{
if (ret == PIO_NOERR)
ERR(ERR_WRONG);
}
else
{
if (ret != PIO_NOERR)
ERR(ERR_WRONG);
}
/* Setting deflate works with parallel iotype starting with netcdf-c-4.7.4. */
if ((ret = PIOc_def_var_deflate(ncid, 0, 0, 1, 1)))
ERR(ret);

/* Check that the inq_varname function works. */
if ((ret = PIOc_inq_varname(ncid, 0, NULL)))
Expand Down Expand Up @@ -1611,9 +1602,9 @@ int test_nc4(int iosysid, int num_flavors, int *flavor, int my_rank)
if (shuffle || !deflate || deflate_level != 1)
ERR(ERR_AWFUL);

/* For parallel netCDF-4, no compression available. :-( */
/* For parallel netCDF-4, we turned on deflate above. */
if (flavor[fmt] == PIO_IOTYPE_NETCDF4P)
if (shuffle || deflate)
if (shuffle || !deflate || deflate_level != 1)
ERR(ERR_AWFUL);

/* Check setting the chunk cache for the variable. */
Expand Down
161 changes: 161 additions & 0 deletions tests/cunit/test_simple.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*
* This very simple test for PIO runs on 4 ranks.
*
* @author Ed Hartnett
*/
#include <config.h>
#include <pio.h>
#include <pio_tests.h>

/* The name of this test. */
#define TEST_NAME "test_simple"
#define DIM_NAME "a_dim"
#define DIM_NAME_UNLIM "an_unlimited_dim"
#define VAR_NAME "a_var"
#define DIM_LEN 4
#define NDIM1 1
#define NDIM2 2

int main(int argc, char **argv)
{
int my_rank;
int ntasks;
int num_iotasks = 1;
int iosysid, ioid;
int gdimlen, elements_per_pe;
PIO_Offset *compmap;
int ncid, dimid[NDIM2], varid;
int num_flavors; /* Number of PIO netCDF flavors in this build. */
int flavor[NUM_FLAVORS]; /* iotypes for the supported netCDF IO flavors. */
int *data, *data_in;
int i, f;
int ret;

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

/* PIOc_set_log_level(4); */
if (ntasks != 1 && ntasks != 4)
{
if (!my_rank)
printf("Test must be run on 1 or 4 tasks.\n");
return ERR_AWFUL;
}

/* Turn off logging, to prevent error messages from being logged
* when we intentionally call functions we know will fail. */
PIOc_set_log_level(-1);

/* Change error handling so we can test inval parameters. */
if ((ret = PIOc_set_iosystem_error_handling(PIO_DEFAULT, PIO_RETURN_ERROR, NULL)))
ERR(ret);

/* Initialize the IOsystem. */
if ((ret = PIOc_Init_Intracomm(MPI_COMM_WORLD, num_iotasks, 1, 0, PIO_REARR_BOX,
&iosysid)))
ERR(ret);

/* Find out which IOtypes are available in this build by calling
* this function from test_common.c. */
if ((ret = get_iotypes(&num_flavors, flavor)))
ERR(ret);

/* Initialize the decomposition. */
gdimlen = DIM_LEN;
elements_per_pe = DIM_LEN/ntasks;
if (!(compmap = malloc(elements_per_pe * sizeof(PIO_Offset))))
ERR(ERR_MEM);
for (i = 0; i < elements_per_pe; i++)
compmap[i] = my_rank + i;
if ((ret = PIOc_init_decomp(iosysid, PIO_INT, NDIM1, &gdimlen, elements_per_pe, compmap,
&ioid, PIO_REARR_BOX, NULL, NULL)))
ERR(ret);
free(compmap);

/* Create one record of data. */
if (!(data = malloc(elements_per_pe * sizeof(int))))
ERR(ERR_MEM);
for (i = 0; i < elements_per_pe; i++)
data[i] = my_rank + i;

/* Storage to read one record back in. */
if (!(data_in = malloc(elements_per_pe * sizeof(int))))
ERR(ERR_MEM);

/* Create a file with each available IOType. */
for (f = 0; f < num_flavors; f++)
{
char filename[NC_MAX_NAME + 1];

/* Create a file. */
sprintf(filename, "%s_%d.nc", TEST_NAME, flavor[f]);
if ((ret = PIOc_createfile(iosysid, &ncid, &flavor[f], filename, NC_CLOBBER)))
ERR(ret);

/* Define dims. */
if ((ret = PIOc_def_dim(ncid, DIM_NAME_UNLIM, PIO_UNLIMITED, &dimid[0])))
ERR(ret);
if ((ret = PIOc_def_dim(ncid, DIM_NAME, DIM_LEN, &dimid[1])))
ERR(ret);

/* Define a var. */
if ((ret = PIOc_def_var(ncid, VAR_NAME, PIO_INT, NDIM2, dimid, &varid)))
ERR(ret);
if ((ret = PIOc_enddef(ncid)))
ERR(ret);

/* Write a record of data. Each compute task writes its local
* array of data. */
if ((ret = PIOc_setframe(ncid, varid, 0)))
ERR(ret);
if ((ret = PIOc_write_darray(ncid, varid, ioid, elements_per_pe, data, NULL)))
ERR(ret);

/* Close the file. */
if ((ret = PIOc_closefile(ncid)))
ERR(ret);

/* Check the file. */
{
/* Reopen the file. */
if ((ret = PIOc_openfile(iosysid, &ncid, &flavor[f], filename, NC_NOWRITE)))
ERR(ret);

/* Read the local array of data for this task and confirm correctness. */
if ((ret = PIOc_setframe(ncid, varid, 0)))
ERR(ret);
if ((ret = PIOc_read_darray(ncid, varid, ioid, elements_per_pe, data_in)))
ERR(ret);
for (i = 0; i < elements_per_pe; i++)
if (data_in[i] != data[i]) ERR(ERR_WRONG);

/* Close the file. */
if ((ret = PIOc_closefile(ncid)))
ERR(ret);
}
} /* next IOType */

/* Free resources. */
free(data);
free(data_in);
if ((ret = PIOc_freedecomp(iosysid, ioid)))
ERR(ret);

/* Finalize the IOsystem. */
if ((ret = PIOc_finalize(iosysid)))
ERR(ret);

printf("%d %s SUCCESS!!\n", my_rank, TEST_NAME);

/* Finalize MPI. */
MPI_Finalize();

return 0;
}
34 changes: 9 additions & 25 deletions tests/unit/ncdf_tests.F90
Original file line number Diff line number Diff line change
Expand Up @@ -469,12 +469,12 @@ Subroutine test_nc4(test_id, err_msg)
! deflate_level_2 = 4
deflate_level = 1
deflate_level_2 = 1
ret_val = PIO_set_log_level(3)
ret_val = PIO_def_var_deflate(pio_file, pio_var, shuffle, deflate, &
deflate_level)

! Should not have worked except for netCDF-4/HDF5 serial.
if (iotype .eq. PIO_iotype_netcdf4c .and. ret_val .ne. PIO_NOERR) then
! Should not have worked except for netCDF-4/HDF5.
if ((iotype .eq. PIO_iotype_netcdf4c .or. iotype .eq. PIO_iotype_netcdf4p) &
.and. ret_val .ne. PIO_NOERR) then
err_msg = "Could not turn on compression for variable foo2222"
call PIO_closefile(pio_file)
return
Expand All @@ -486,10 +486,6 @@ Subroutine test_nc4(test_id, err_msg)
err_msg = "Did not get expected error when trying to turn deflate on for netcdf classic file"
call PIO_closefile(pio_file)
return
else if (iotype .eq. PIO_iotype_netcdf4p .and. ret_val .eq. PIO_NOERR) then
err_msg = "Did not get expected error when trying to turn deflate on for parallel netcdf-4 file"
call PIO_closefile(pio_file)
return
end if

print*, 'testing PIO_put_att'
Expand All @@ -514,8 +510,8 @@ Subroutine test_nc4(test_id, err_msg)
print*, 'testing PIO_inq_var_deflate'
ret_val = PIO_inq_var_deflate(pio_file, pio_var, shuffle, deflate, my_deflate_level)

! Should not have worked except for netCDF-4/HDF5 serial.
if (iotype .eq. PIO_iotype_netcdf4c) then
! Should not have worked except for netCDF-4/HDF5.
if (iotype .eq. PIO_iotype_netcdf4c .or. iotype .eq. PIO_iotype_netcdf4p) then
if (ret_val .ne. PIO_NOERR) then
err_msg = "Got error trying to inquire about deflate on for serial netcdf-4 file"
call PIO_closefile(pio_file)
Expand All @@ -532,26 +528,14 @@ Subroutine test_nc4(test_id, err_msg)
err_msg = "Did not get expected error when trying to check deflate for non-netcdf-4 file"
call PIO_closefile(pio_file)
return
else if (iotype .eq. PIO_iotype_netcdf4p) then
if (ret_val .ne. PIO_NOERR) then
err_msg = "Got error trying to inquire about deflate on for parallel netcdf-4 file"
call PIO_closefile(pio_file)
return
else
if (shuffle .ne. 0 .or. deflate .ne. 0) then
err_msg = "Wrong values for deflate and shuffle for parallel netcdf-4 file"
call PIO_closefile(pio_file)
return
end if
end if
end if

! Try to turn on compression for this variable.
print*, 'testing PIO_def_var_deflate'
ret_val = PIO_def_var_deflate(pio_file, pio_var%varid, shuffle, deflate, &
deflate_level_2)

! Should not have worked except for netCDF-4/HDF5 serial.
! Should not have worked except for netCDF-4/HDF5.
if (iotype .eq. PIO_iotype_netcdf4c .and. ret_val .ne. PIO_NOERR) then
err_msg = "Could not turn on compression for variable foo2222 second time"
call PIO_closefile(pio_file)
Expand All @@ -564,8 +548,8 @@ Subroutine test_nc4(test_id, err_msg)
err_msg = "Did not get expected error when trying to turn deflate on for netcdf classic file"
call PIO_closefile(pio_file)
return
else if (iotype .eq. PIO_iotype_netcdf4p .and. ret_val .eq. PIO_NOERR) then
err_msg = "Did not get expected error when trying to turn deflate on for parallel netcdf-4 file"
else if (iotype .eq. PIO_iotype_netcdf4p .and. ret_val .ne. PIO_NOERR) then
err_msg = "Could not turn on compression for variable foo2222 second time"
call PIO_closefile(pio_file)
return
end if
Expand Down Expand Up @@ -605,7 +589,7 @@ Subroutine test_nc4(test_id, err_msg)
call PIO_closefile(pio_file)
return
else
if (shuffle .ne. 0 .or. deflate .ne. 0) then
if (shuffle .ne. 0 .or. deflate .ne. 1 .or. my_deflate_level .ne. deflate_level_2) then
err_msg = "Wrong values for deflate and shuffle for parallel netcdf-4 file"
call PIO_closefile(pio_file)
return
Expand Down

0 comments on commit a14b65b

Please sign in to comment.