diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ddaf9a15b88..b13a09dbebb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,18 +14,28 @@ mark_as_advanced(VERSION_MAJOR VERSION_MINOR VERSION_PATCH) #===== Library Options ===== option (PIO_ENABLE_FORTRAN "Enable the Fortran library builds" ON) option (PIO_ENABLE_TIMING "Enable the use of the GPTL timing library" ON) +option (PIO_ENABLE_ASYNC "Enable the use of asychronus IO operations" OFF) +option (PIO_ENABLE_LOGGING "Enable debug logging (large output possible)" OFF) option (PIO_TEST_BIG_ENDIAN "Enable test to see if machine is big endian" ON) option (PIO_USE_MPIIO "Enable support for MPI-IO auto detect" ON) option (PIO_USE_MPISERIAL "Enable mpi-serial support (instead of MPI)" OFF) option (PIO_USE_MALLOC "Use native malloc (instead of bget package)" OFF) option (WITH_PNETCDF "Require the use of PnetCDF" ON) +# Set a variable that appears in the config.h.in file. if(PIO_USE_MALLOC) set(USE_MALLOC 1) else() set(USE_MALLOC 0) endif() +# Set a variable that appears in the config.h.in file. +if(PIO_ENABLE_LOGGING) + set(ENABLE_LOGGING 1) +else() + set(ENABLE_LOGGING 0) +endif() + #===== Library Variables ===== set (PIO_FILESYSTEM_HINTS IGNORE CACHE STRING "Filesystem hints (lustre or gpfs)") diff --git a/src/clib/CMakeLists.txt b/src/clib/CMakeLists.txt index 093aeac70c16..4344261aa281 100644 --- a/src/clib/CMakeLists.txt +++ b/src/clib/CMakeLists.txt @@ -15,14 +15,20 @@ set (PIO_C_SRCS topology.c pio_spmd.c pio_rearrange.c pio_darray.c + pio_nc4.c bget.c) -set (PIO_GENNC_SRCS ${CMAKE_CURRENT_BINARY_DIR}/pio_nc.c - ${CMAKE_CURRENT_BINARY_DIR}/pio_nc4.c - ${CMAKE_CURRENT_BINARY_DIR}/pio_put_nc.c - ${CMAKE_CURRENT_BINARY_DIR}/pio_get_nc.c) +set (PIO_GENNC_SRCS ${CMAKE_CURRENT_BINARY_DIR}/pio_put_nc.c + ${CMAKE_CURRENT_BINARY_DIR}/pio_get_nc.c + ${CMAKE_CURRENT_BINARY_DIR}/pio_nc.c) -add_library (pioc ${PIO_C_SRCS} ${PIO_GENNC_SRCS}) +if (PIO_ENABLE_ASYNC) + set (PIO_ADDL_SRCS pio_nc_async.c pio_put_nc_async.c pio_get_nc_async.c pio_msg.c pio_varm.c) +else () + set (PIO_ADDL_SRCS ${PIO_GENNC_SRCS}) +endif () + +add_library (pioc ${PIO_C_SRCS} ${PIO_ADDL_SRCS}) # set up include-directories include_directories( @@ -196,12 +202,9 @@ else () pio_get_nc.c COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/pio_nc.c pio_nc.c - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/pio_nc4.c - pio_nc4.c DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/pio_put_nc.c ${CMAKE_CURRENT_SOURCE_DIR}/pio_get_nc.c - ${CMAKE_CURRENT_SOURCE_DIR}/pio_nc.c - ${CMAKE_CURRENT_SOURCE_DIR}/pio_nc4.c) + ${CMAKE_CURRENT_SOURCE_DIR}/pio_nc.c) endif () diff --git a/src/clib/config.h.in b/src/clib/config.h.in index e4be61d9e0c7..1722872c3056 100644 --- a/src/clib/config.h.in +++ b/src/clib/config.h.in @@ -19,4 +19,7 @@ * will use the included bget() package for memory management. */ #define PIO_USE_MALLOC @USE_MALLOC@ +/** Set to non-zero to turn on logging. Output may be large. */ +#define PIO_ENABLE_LOGGING @ENABLE_LOGGING@ + #endif /* _PIO_CONFIG_ */ diff --git a/src/clib/pio.h b/src/clib/pio.h index 5185a133b0e5..d7710f9f4aed 100644 --- a/src/clib/pio.h +++ b/src/clib/pio.h @@ -259,6 +259,10 @@ typedef struct file_desc_t int mode; struct wmulti_buffer buffer; struct file_desc_t *next; + + /** True if this task should participate in IO (only true for one + * task with netcdf serial files. */ + int do_io; } file_desc_t; /** @@ -409,8 +413,8 @@ int PIOc_inq_varnatts (int ncid, int varid, int *nattsp); int PIOc_def_var (int ncid, const char *name, nc_type xtype, int ndims, const int *dimidsp, int *varidp); int PIOc_def_var_deflate(int ncid, int varid, int shuffle, int deflate, int deflate_level); -int PIOc_inq_var_deflate(int ncid, int varid, int *shufflep, - int *deflatep, int *deflate_levelp); +int PIOc_inq_var_deflate(int ncid, int varid, int *shufflep, int *deflatep, + int *deflate_levelp); int PIOc_inq_var_szip(int ncid, int varid, int *options_maskp, int *pixels_per_blockp); int PIOc_def_var_chunking(int ncid, int varid, int storage, const PIO_Offset *chunksizesp); int PIOc_inq_var_chunking(int ncid, int varid, int *storagep, PIO_Offset *chunksizesp); @@ -481,6 +485,8 @@ int PIOc_InitDecomp(const int iosysid, const int basetype,const int ndims, const int PIOc_Init_Intracomm(const MPI_Comm comp_comm, const int num_iotasks, const int stride, const int base, const int rearr, int *iosysidp); +int PIOc_Init_Intercomm(int component_count, MPI_Comm peer_comm, MPI_Comm *comp_comms, + MPI_Comm io_comm, int *iosysidp); int PIOc_closefile(int ncid); int PIOc_createfile(const int iosysid, int *ncidp, int *iotype, const char *fname, const int mode); @@ -586,10 +592,11 @@ int PIOc_set_blocksize(const int newblocksize); int PIOc_put_vars_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const long long *op); int PIOc_put_vara_double (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const double *op); int PIOc_put_vars (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const void *buf, PIO_Offset bufcount, MPI_Datatype buftype); + int PIOc_put_vars_tc(int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], nc_type xtype, const void *buf); int PIOc_put_var_uchar (int ncid, int varid, const unsigned char *op); int PIOc_put_var_long (int ncid, int varid, const long *op); int PIOc_put_varm_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const long long *op); - int PIOc_get_vara_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], int *buf); + int PIOc_get_vara_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], int *buf); int PIOc_get_var1_float (int ncid, int varid, const PIO_Offset index[], float *buf); int PIOc_get_var1_short (int ncid, int varid, const PIO_Offset index[], short *buf); int PIOc_get_vars_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], int *buf); @@ -641,11 +648,15 @@ int PIOc_set_blocksize(const int newblocksize); int PIOc_get_vars_text (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], char *buf); int PIOc_get_var1_uchar (int ncid, int varid, const PIO_Offset index[], unsigned char *buf); int PIOc_get_vars (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], void *buf, PIO_Offset bufcount, MPI_Datatype buftype); + int PIOc_get_vars_tc(int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], nc_type xtype, void *buf); int PIOc_get_varm_short (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], short *buf); int PIOc_get_varm_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned long long *buf); int PIOc_get_var_schar (int ncid, int varid, signed char *buf); int PIOc_iotype_available(const int iotype); - + int PIOc_set_log_level(int level); + int PIOc_put_att(int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const void *op); + int PIOc_get_att(int ncid, int varid, const char *name, void *ip); + int PIOc_inq_type(int ncid, nc_type xtype, char *name, PIO_Offset *sizep); #if defined(__cplusplus) } #endif diff --git a/src/clib/pio_file.c b/src/clib/pio_file.c index 461c8d2b4ca3..b3e8f9dc021e 100644 --- a/src/clib/pio_file.c +++ b/src/clib/pio_file.c @@ -1,3 +1,4 @@ +#include #include #include /** @@ -13,28 +14,35 @@ */ int PIOc_openfile(const int iosysid, int *ncidp, int *iotype, - const char filename[], const int mode) + const char *filename, const int mode) { - int ierr; - int msg; - int mpierr; + int msg = PIO_MSG_OPEN_FILE; size_t len; iosystem_desc_t *ios; file_desc_t *file; + int ierr = PIO_NOERR; + int mpierr = MPI_SUCCESS; - ierr = PIO_NOERR; + LOG((1, "PIOc_openfile iosysid = %d", iosysid)); - msg = PIO_MSG_OPEN_FILE; - ios = pio_get_iosystem_from_id(iosysid); - if(ios==NULL){ - printf("bad iosysid %d\n",iosysid); - return PIO_EBADID; + /* Get the IO system info from the iosysid. */ + if (!(ios = pio_get_iosystem_from_id(iosysid))) + { + printf("bad iosysid %d\n",iosysid); + return PIO_EBADID; } - file = (file_desc_t *) malloc(sizeof(*file)); - if(file==NULL){ - return PIO_ENOMEM; - } + /* User must provide valid input for these parameters. */ + if (!ncidp || !iotype || !filename) + return PIO_EINVAL; + if (*iotype < PIO_IOTYPE_PNETCDF || *iotype > PIO_IOTYPE_NETCDF4P) + return PIO_ENOMEM; + + /* Allocate space for the file info. */ + if (!(file = (file_desc_t *) malloc(sizeof(*file)))) + return PIO_ENOMEM; + + /* Fill in some file values. */ file->iotype = *iotype; file->next = NULL; file->iosystem = ios; @@ -57,19 +65,43 @@ int PIOc_openfile(const int iosysid, int *ncidp, int *iotype, file->buffer.frame=NULL; file->buffer.fillvalue=NULL; - if(ios->async_interface && ! ios->ioproc){ - if(ios->comp_rank==0) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - len = strlen(filename); - mpierr = MPI_Bcast(&len, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast((void *)filename, len + 1, MPI_CHAR, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&file->iotype, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&file->mode, 1, MPI_INT, ios->compmaster, ios->intercomm); - } + /** Set to true if this task should participate in IO (only true for + * one task with netcdf serial files. */ + if (file->iotype == PIO_IOTYPE_NETCDF4P || file->iotype == PIO_IOTYPE_PNETCDF || + ios->io_rank == 0) + file->do_io = 1; + else + file->do_io = 0; + + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + if(ios->comp_rank==0) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + len = strlen(filename); + if (!mpierr) + mpierr = MPI_Bcast(&len, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)filename, len + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&file->iotype, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&file->mode, 1, MPI_INT, ios->compmaster, ios->intercomm); + } - if(ios->ioproc){ + /* Handle MPI errors. */ + mpierr = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm); + check_mpi(file, mpierr, __FILE__, __LINE__); + } - switch(file->iotype){ + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { + switch (file->iotype) + { #ifdef _NETCDF #ifdef _NETCDF4 @@ -78,7 +110,7 @@ int PIOc_openfile(const int iosysid, int *ncidp, int *iotype, ierr = nc_open(filename, file->mode, &(file->fh)); #else file->mode = file->mode | NC_MPIIO; - ierr = nc_open_par(filename, file->mode, ios->io_comm,ios->info, &(file->fh)); + ierr = nc_open_par(filename, file->mode, ios->io_comm, ios->info, &file->fh); #endif break; @@ -89,18 +121,20 @@ int PIOc_openfile(const int iosysid, int *ncidp, int *iotype, case PIO_IOTYPE_NETCDF: if(ios->io_rank==0){ - ierr = nc_open(filename, file->mode, &(file->fh)); + ierr = nc_open(filename, file->mode, &file->fh); } break; #endif #ifdef _PNETCDF case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_open(ios->io_comm, filename, file->mode, ios->info, &(file->fh)); + ierr = ncmpi_open(ios->io_comm, filename, file->mode, ios->info, &file->fh); // This should only be done with a file opened to append - if(ierr == PIO_NOERR && (file->mode & PIO_WRITE)){ - if(ios->iomaster) printf("%d Setting IO buffer %ld\n",__LINE__,PIO_BUFFER_SIZE_LIMIT); + if (ierr == PIO_NOERR && (file->mode & PIO_WRITE)) + { + if(ios->iomaster) + printf("%d Setting IO buffer %ld\n",__LINE__,PIO_BUFFER_SIZE_LIMIT); ierr = ncmpi_buffer_attach(file->fh, PIO_BUFFER_SIZE_LIMIT ); } break; @@ -113,35 +147,45 @@ int PIOc_openfile(const int iosysid, int *ncidp, int *iotype, // If we failed to open a file due to an incompatible type of NetCDF, try it // once with just plain old basic NetCDF -#ifdef _NETCDF - if((ierr == NC_ENOTNC || ierr == NC_EINVAL) && (file->iotype != PIO_IOTYPE_NETCDF)) { - if(ios->iomaster) printf("PIO2 pio_file.c retry NETCDF\n"); - // reset ierr on all tasks - ierr = PIO_NOERR; - // reset file markers for NETCDF on all tasks - file->iotype = PIO_IOTYPE_NETCDF; - - // open netcdf file serially on main task - if(ios->io_rank==0){ - ierr = nc_open(filename, file->mode, &(file->fh)); } - - } -#endif +/* #ifdef _NETCDF */ +/* if((ierr == NC_ENOTNC || ierr == NC_EINVAL) && (file->iotype != PIO_IOTYPE_NETCDF)) { */ +/* if(ios->iomaster) printf("PIO2 pio_file.c retry NETCDF\n"); */ +/* // reset ierr on all tasks */ +/* ierr = PIO_NOERR; */ +/* // reset file markers for NETCDF on all tasks */ +/* file->iotype = PIO_IOTYPE_NETCDF; */ + +/* // open netcdf file serially on main task */ +/* if(ios->io_rank==0){ */ +/* ierr = nc_open(filename, file->mode, &(file->fh)); } */ + +/* } */ +/* #endif */ } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if (!ierr) { - mpierr = MPI_Bcast(&file->mode, 1, MPI_INT, ios->ioroot, ios->union_comm); - mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->ioroot, ios->union_comm); - *ncidp = file->fh; - pio_add_to_file_list(file); - *ncidp = file->fh; + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return PIO_EIO; + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. Ignore NULL parameters. */ + if (!ierr) + { + if ((mpierr = MPI_Bcast(&file->mode, 1, MPI_INT, ios->ioroot, ios->union_comm))) + return PIO_EIO; + + if ((mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->ioroot, ios->union_comm))) + return PIO_EIO; + + *ncidp = file->fh; + pio_add_to_file_list(file); } - if(ios->io_rank==0){ - printf("Open file %s %d\n",filename,file->fh); //,file->fh,file->id,ios->io_rank,ierr); + + if (ios->io_rank==0){ + printf("Open file %s %d\n",filename,file->fh); //,file->fh,file->id,ios->io_rank,ierr); // if(file->fh==5) print_trace(stdout); } + return ierr; } @@ -157,7 +201,7 @@ int PIOc_openfile(const int iosysid, int *ncidp, int *iotype, ** @param mode : The netcdf mode for the open operation */ -int PIOc_createfile(const int iosysid, int *ncidp, int *iotype, +int PIOc_createfile(const int iosysid, int *ncidp, int *iotype, const char filename[], const int mode) { int ierr; @@ -199,18 +243,37 @@ int PIOc_createfile(const int iosysid, int *ncidp, int *iotype, msg = PIO_MSG_CREATE_FILE; file->mode = mode; + /** Set to true if this task should participate in IO (only true for + * one task with netcdf serial files. */ + if (file->iotype == PIO_IOTYPE_NETCDF4P || file->iotype == PIO_IOTYPE_PNETCDF || + ios->io_rank == 0) + file->do_io = 1; + else + file->do_io = 0; + + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + if(ios->comp_rank==0) + mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm); + len = strlen(filename); + if (!mpierr) + mpierr = MPI_Bcast(&len, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)filename, len + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&file->iotype, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&file->mode, 1, MPI_INT, ios->compmaster, ios->intercomm); + } - if(ios->async_interface && ! ios->ioproc){ - if(ios->comp_rank==0) - mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm); - len = strlen(filename); - mpierr = MPI_Bcast(&len, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast((void *)filename, len + 1, MPI_CHAR, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&file->iotype, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&file->mode, 1, MPI_INT, ios->compmaster, ios->intercomm); - } + /* Handle MPI errors. */ + mpierr = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm); + check_mpi(file, mpierr, __FILE__, __LINE__); + } - if(ios->ioproc){ switch(file->iotype){ #ifdef _NETCDF @@ -252,9 +315,9 @@ int PIOc_createfile(const int iosysid, int *ncidp, int *iotype, ierr = check_netcdf(file, ierr, __FILE__,__LINE__); if(ierr == PIO_NOERR){ - mpierr = MPI_Bcast(&file->mode, 1, MPI_INT, ios->ioroot, ios->union_comm); + mpierr = MPI_Bcast(&file->mode, 1, MPI_INT, ios->ioroot, ios->union_comm); file->mode = file->mode | PIO_WRITE; // This flag is implied by netcdf create functions but we need to know if its set - mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->ioroot, ios->union_comm); + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->ioroot, ios->union_comm); *ncidp = file->fh; pio_add_to_file_list(file); *ncidp = file->fh; @@ -367,7 +430,7 @@ int PIOc_deletefile(const int iosysid, const char filename[]) if(ios->comp_rank==0) mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); len = strlen(filename); - mpierr = MPI_Bcast(&len, 1, MPI_INT, ios->compmaster, ios->intercomm); + mpierr = MPI_Bcast(&len, 1, MPI_INT, ios->compmaster, ios->intercomm); mpierr = MPI_Bcast((void *)filename, len + 1, MPI_CHAR, ios->compmaster, ios->intercomm); } // The barriers are needed to assure that no task is trying to operate on the file while it is being deleted. @@ -399,7 +462,7 @@ int PIOc_deletefile(const int iosysid, const char filename[]) /** * @name PIOc_sync */ -int PIOc_sync (int ncid) +int PIOc_sync(int ncid) { int ierr; int msg; diff --git a/src/clib/pio_get_nc_async.c b/src/clib/pio_get_nc_async.c index 0da690aaf216..610f0a6cfd33 100644 --- a/src/clib/pio_get_nc_async.c +++ b/src/clib/pio_get_nc_async.c @@ -1,4988 +1,869 @@ +#include #include #include -int PIOc_get_var1_schar (int ncid, int varid, const PIO_Offset index[], signed char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_SCHAR; - ibuftype = MPI_CHAR; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_schar(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_schar(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_schar(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_schar_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], unsigned long long *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_ULONGLONG; - ibuftype = MPI_UNSIGNED_LONG_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_ulonglong(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_ulonglong_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_varm_uchar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_UCHAR; - ibuftype = MPI_UNSIGNED_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_uchar(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_uchar_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_varm_schar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], signed char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_SCHAR; - ibuftype = MPI_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_schar(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_schar_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_short (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], short *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_SHORT; - ibuftype = MPI_SHORT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_short(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_short_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var_double (int ncid, int varid, double *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_DOUBLE; - ibuftype = MPI_DOUBLE; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_double(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_double(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_double(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_double_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_double (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], double *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_DOUBLE; - ibuftype = MPI_DOUBLE; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_double(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_double(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_double(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_double_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var_int (int ncid, int varid, int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_INT; - ibuftype = MPI_INT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_int(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_int(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_int(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_int_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var_ushort (int ncid, int varid, unsigned short *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_USHORT; - ibuftype = MPI_UNSIGNED_SHORT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_ushort(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_ushort(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_ushort(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_ushort_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_text (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_TEXT; - ibuftype = MPI_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_text(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_text(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_text(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_text_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_INT; - ibuftype = MPI_INT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_int(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_int(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_int(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_int_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1_float (int ncid, int varid, const PIO_Offset index[], float *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_FLOAT; - ibuftype = MPI_FLOAT; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_float(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_float(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_float(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_float_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1_short (int ncid, int varid, const PIO_Offset index[], short *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_SHORT; - ibuftype = MPI_SHORT; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_short(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_short(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_short(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_short_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_INT; - ibuftype = MPI_INT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_int(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_int_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var_text (int ncid, int varid, char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_TEXT; - ibuftype = MPI_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_text(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_text(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_text(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_text_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_varm_double (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], double *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_DOUBLE; - ibuftype = MPI_DOUBLE; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_double(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_double_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_schar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], signed char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_SCHAR; - ibuftype = MPI_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_schar(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_schar_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_ushort (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], unsigned short *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_USHORT; - ibuftype = MPI_UNSIGNED_SHORT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_ushort(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_ushort(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_ushort(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_ushort_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1_ushort (int ncid, int varid, const PIO_Offset index[], unsigned short *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_USHORT; - ibuftype = MPI_UNSIGNED_SHORT; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_ushort(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_ushort(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_ushort(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_ushort_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var_float (int ncid, int varid, float *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_FLOAT; - ibuftype = MPI_FLOAT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_float(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_float(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_float(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_float_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_uchar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], unsigned char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_UCHAR; - ibuftype = MPI_UNSIGNED_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_uchar(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_uchar_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var (int ncid, int varid, void *buf, PIO_Offset bufcount, MPI_Datatype buftype) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR; - ibufcnt = bufcount; - ibuftype = buftype; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var(file->fh, varid, buf, bufcount, buftype);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_all(file->fh, varid, buf, bufcount, buftype);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1_longlong (int ncid, int varid, const PIO_Offset index[], long long *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_LONGLONG; - ibuftype = MPI_LONG_LONG; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_longlong(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_longlong(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_longlong(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_longlong_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_ushort (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], unsigned short *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_USHORT; - ibuftype = MPI_UNSIGNED_SHORT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_ushort(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_ushort_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var_long (int ncid, int varid, long *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_LONG; - ibuftype = MPI_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_long(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_long(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_long(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_long_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1_double (int ncid, int varid, const PIO_Offset index[], double *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_DOUBLE; - ibuftype = MPI_DOUBLE; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_double(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_double(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_double(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_double_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_uint (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], unsigned int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_UINT; - ibuftype = MPI_UNSIGNED; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_uint(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_uint(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_uint(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_uint_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], long long *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_LONGLONG; - ibuftype = MPI_LONG_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_longlong(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_longlong_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var_longlong (int ncid, int varid, long long *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_LONGLONG; - ibuftype = MPI_LONG_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_longlong(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_longlong(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_longlong(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_longlong_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_short (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], short *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_SHORT; - ibuftype = MPI_SHORT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_short(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_short(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_short(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_short_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_long (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], long *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_LONG; - ibuftype = MPI_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_long(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_long(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_long(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_long_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1_int (int ncid, int varid, const PIO_Offset index[], int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_INT; - ibuftype = MPI_INT; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_int(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_int(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_int(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_int_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1_ulonglong (int ncid, int varid, const PIO_Offset index[], unsigned long long *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_ULONGLONG; - ibuftype = MPI_UNSIGNED_LONG_LONG; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_ulonglong(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_ulonglong(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_ulonglong(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_ulonglong_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var_uchar (int ncid, int varid, unsigned char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_UCHAR; - ibuftype = MPI_UNSIGNED_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_uchar(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_uchar(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_uchar(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_uchar_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_uchar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], unsigned char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_UCHAR; - ibuftype = MPI_UNSIGNED_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_uchar(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_uchar(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_uchar(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_uchar_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_float (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], float *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_FLOAT; - ibuftype = MPI_FLOAT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_float(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_float(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_float(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_float_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_long (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], long *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_LONG; - ibuftype = MPI_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_long(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_long_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1 (int ncid, int varid, const PIO_Offset index[], void *buf, PIO_Offset bufcount, MPI_Datatype buftype) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1; - ibufcnt = bufcount; - ibuftype = buftype; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1(file->fh, varid, index, buf, bufcount, buftype);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_all(file->fh, varid, index, buf, bufcount, buftype);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var_uint (int ncid, int varid, unsigned int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_UINT; - ibuftype = MPI_UNSIGNED; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_uint(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_uint(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_uint(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_uint_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], void *buf, PIO_Offset bufcount, MPI_Datatype buftype) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA; - ibufcnt = bufcount; - ibuftype = buftype; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara(file->fh, varid, start, count, buf, bufcount, buftype);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_all(file->fh, varid, start, count, buf, bufcount, buftype);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_schar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], signed char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_SCHAR; - ibuftype = MPI_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_schar(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_schar(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_schar(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_schar_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1_uint (int ncid, int varid, const PIO_Offset index[], unsigned int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_UINT; - ibuftype = MPI_UNSIGNED; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_uint(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_uint(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_uint(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_uint_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vars_uint (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], unsigned int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_UINT; - ibuftype = MPI_UNSIGNED; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_uint(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_uint_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_vara_float (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], float *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_FLOAT; - ibuftype = MPI_FLOAT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_float(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_float(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_float(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_float_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_varm_text (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_TEXT; - ibuftype = MPI_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_text(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_text_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_var1_text (int ncid, int varid, const PIO_Offset index[], char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_TEXT; - ibuftype = MPI_CHAR; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_text(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_text(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_text(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_text_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_varm_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_INT; - ibuftype = MPI_INT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_int(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_int_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_varm_uint (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned int *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_UINT; - ibuftype = MPI_UNSIGNED; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_uint(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_uint_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; -} - -int PIOc_get_varm (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], void *buf, PIO_Offset bufcount, MPI_Datatype buftype) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM; - ibufcnt = bufcount; - ibuftype = buftype; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm(file->fh, varid, start, count, stride, imap, buf, bufcount, buftype);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_all(file->fh, varid, start, count, stride, imap, buf, bufcount, buftype);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +int PIOc_get_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, nc_type xtype, void *buf) +{ + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ + int ndims; /** The number of dimensions in the variable. */ + int *dimids; /** The IDs of the dimensions for this variable. */ + PIO_Offset typelen; /** Size (in bytes) of the data type of data in buf. */ + size_t num_elem = 1; /** Number of data elements in the buffer. */ + int bcast = false; + + LOG((1, "PIOc_get_vars_tc ncid = %d varid = %d start = %d count = %d " + "stride = %d xtype = %d", ncid, varid, start, count, stride, xtype)); + + /* User must provide a place to put some data. */ + if (!buf) + return PIO_EINVAL; + + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; + ios = file->iosystem; + + /* Run these on all tasks if async is not in use, but only on + * non-IO tasks if async is in use. */ + if (!ios->async_interface || !ios->ioproc) + { + /* Get the length of the data type. */ + if ((ierr = PIOc_inq_type(ncid, xtype, NULL, &typelen))) + return check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Get the number of dims for this var. */ + if ((ierr = PIOc_inq_varndims(ncid, varid, &ndims))) + return check_netcdf(file, ierr, __FILE__, __LINE__); + + PIO_Offset dimlen[ndims]; + + /* If no count array was passed, we need to know the dimlens + * so we can calculate how many data elements are in the + * buf. */ + if (!count) + { + int dimid[ndims]; + + /* Get the dimids for this var. */ + if ((ierr = PIOc_inq_vardimid(ncid, varid, dimid))) + return check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Get the length of each dimension. */ + for (int vd = 0; vd < ndims; vd++) + if ((ierr = PIOc_inq_dimlen(ncid, dimid[vd], &dimlen[vd]))) + return check_netcdf(file, ierr, __FILE__, __LINE__); + } + + /* Figure out the real start, count, and stride arrays. (The + * user may have passed in NULLs.) */ + PIO_Offset rstart[ndims], rcount[ndims], rstride[ndims]; + for (int vd = 0; vd < ndims; vd++) + { + rstart[vd] = start ? start[vd] : 0; + rcount[vd] = count ? count[vd] : dimlen[vd]; + rstride[vd] = stride ? stride[vd] : 1; + } + + /* How many elements in buf? */ + for (int vd = 0; vd < ndims; vd++) + num_elem *= (rcount[vd] - rstart[vd])/rstride[vd]; + LOG((2, "PIOc_put_vars_tc num_elem = %d", num_elem)); + } + + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_GET_VARS; + char start_present = start ? true : false; + char count_present = count ? true : false; + char stride_present = stride ? true : false; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm); + + /* Send the function parameters and associated informaiton + * to the msg handler. */ + if (!mpierr) + mpierr = MPI_Bcast(&ncid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&ndims, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&start_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr && start_present) + mpierr = MPI_Bcast((PIO_Offset *)start, ndims, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&count_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr && count_present) + mpierr = MPI_Bcast((PIO_Offset *)count, ndims, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&stride_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr && stride_present) + mpierr = MPI_Bcast((PIO_Offset *)stride, ndims, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&xtype, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&num_elem, 1, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, ios->compmaster, ios->intercomm); + LOG((2, "PIOc_get_vars_tc ncid = %d varid = %d ndims = %d start_present = %d " + "count_present = %d stride_present = %d xtype = %d num_elem = %d", ncid, varid, + ndims, start_present, count_present, stride_present, xtype, num_elem)); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + + /* Broadcast values currently only known on computation tasks to IO tasks. */ + if ((mpierr = MPI_Bcast(&num_elem, 1, MPI_OFFSET, ios->comproot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + if ((mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, ios->comproot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { +#ifdef _PNETCDF + if (file->iotype == PIO_IOTYPE_PNETCDF) + { +#ifdef PNET_READ_AND_BCAST + LOG((1, "PNET_READ_AND_BCAST")); + ncmpi_begin_indep_data(file->fh); + if (ios->iomaster) + { + switch(xtype) + { + case NC_BYTE: + ierr = ncmpi_get_vars_schar(ncid, varid, start, count, stride, buf); + break; + case NC_CHAR: + ierr = ncmpi_get_vars_text(ncid, varid, start, count, stride, buf); + break; + case NC_SHORT: + ierr = ncmpi_get_vars_short(ncid, varid, start, count, stride, buf); + break; + case NC_INT: + ierr = ncmpi_get_vars_int(ncid, varid, start, count, stride, buf); + break; + case NC_FLOAT: + ierr = ncmpi_get_vars_float(ncid, varid, start, count, stride, buf); + break; + case NC_DOUBLE: + ierr = ncmpi_get_vars_double(ncid, varid, start, count, stride, buf); + break; + case NC_INT64: + ierr = ncmpi_get_vars_longlong(ncid, varid, start, count, stride, buf); + break; + default: + LOG((0, "Unknown type for pnetcdf file! xtype = %d", xtype)); + } + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else /* PNET_READ_AND_BCAST */ + LOG((1, "not PNET_READ_AND_BCAST")); + switch(xtype) + { + case NC_BYTE: + ierr = ncmpi_get_vars_schar_all(ncid, varid, start, count, stride, buf); + break; + case NC_CHAR: + ierr = ncmpi_get_vars_text_all(ncid, varid, start, count, stride, buf); + break; + case NC_SHORT: + ierr = ncmpi_get_vars_short_all(ncid, varid, start, count, stride, buf); + break; + case NC_INT: + ierr = ncmpi_get_vars_int_all(ncid, varid, start, count, stride, buf); + for (int i = 0; i < 4; i++) + LOG((2, "((int *)buf)[%d] = %d", i, ((int *)buf)[0])); + break; + case NC_FLOAT: + ierr = ncmpi_get_vars_float_all(ncid, varid, start, count, stride, buf); + break; + case NC_DOUBLE: + ierr = ncmpi_get_vars_double_all(ncid, varid, start, count, stride, buf); + break; + case NC_INT64: + ierr = ncmpi_get_vars_longlong_all(ncid, varid, start, count, stride, buf); + break; + default: + LOG((0, "Unknown type for pnetcdf file! xtype = %d", xtype)); + } +#endif /* PNET_READ_AND_BCAST */ + } +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + switch(xtype) + { + case NC_BYTE: + ierr = nc_get_vars_schar(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_CHAR: + ierr = nc_get_vars_schar(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_SHORT: + ierr = nc_get_vars_short(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_INT: + ierr = nc_get_vars_int(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_FLOAT: + ierr = nc_get_vars_float(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_DOUBLE: + ierr = nc_get_vars_double(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; +#ifdef _NETCDF4 + case NC_UBYTE: + ierr = nc_get_vars_uchar(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_USHORT: + ierr = nc_get_vars_ushort(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_UINT: + ierr = nc_get_vars_uint(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_INT64: + ierr = nc_get_vars_longlong(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_UINT64: + ierr = nc_get_vars_ulonglong(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + /* case NC_STRING: */ + /* ierr = nc_get_vars_string(ncid, varid, (size_t *)start, (size_t *)count, */ + /* (ptrdiff_t *)stride, (void *)buf); */ + /* break; */ + default: + ierr = nc_get_vars(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); +#endif /* _NETCDF4 */ + } +#endif /* _NETCDF */ + } + + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + if (ierr) + return check_netcdf(file, ierr, __FILE__, __LINE__); - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; + /* Send the data. */ + LOG((2, "PIOc_get_vars_tc bcasting data num_elem = %d typelen = %d", num_elem, + typelen)); + if (!mpierr) + mpierr = MPI_Bcast((void *)buf, num_elem * typelen, MPI_BYTE, ios->ioroot, + ios->my_comm); + return ierr; } -int PIOc_get_vars_double (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], double *buf) +int PIOc_get_vars_text (int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, char *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_DOUBLE; - ibuftype = MPI_DOUBLE; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_double(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vars_double_all(file->fh, varid, start, count, stride, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_CHAR, buf); } -int PIOc_get_vara_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], long long *buf) +int PIOc_get_vars_uchar(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, unsigned char *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_LONGLONG; - ibuftype = MPI_LONG_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_longlong(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_longlong(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_longlong(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_longlong_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_UBYTE, buf); } -int PIOc_get_var_ulonglong (int ncid, int varid, unsigned long long *buf) +int PIOc_get_vars_schar (int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, signed char *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_ULONGLONG; - ibuftype = MPI_UNSIGNED_LONG_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_ulonglong(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_ulonglong(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_ulonglong(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_ulonglong_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_BYTE, buf); } -int PIOc_get_vara_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], unsigned long long *buf) +int PIOc_get_vars_ushort(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, unsigned short *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARA_ULONGLONG; - ibuftype = MPI_UNSIGNED_LONG_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vara_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vara_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vara_ulonglong(file->fh, varid, start, count, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_vara_ulonglong_all(file->fh, varid, start, count, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - - return ierr; + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_USHORT, buf); } -int PIOc_get_var_short (int ncid, int varid, short *buf) +int PIOc_get_vars_short(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, short *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_SHORT; - ibuftype = MPI_SHORT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_SHORT, buf); +} +int PIOc_get_vars_uint(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, unsigned int *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_UINT, buf); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_short(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_short(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_short(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var_short_all(file->fh, varid, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +int PIOc_get_vars_int(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, int *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_INT, buf); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +int PIOc_get_vars_long(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, long *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_LONG, buf); +} - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } +int PIOc_get_vars_float(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, float *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_FLOAT, buf); +} - return ierr; +int PIOc_get_vars_double(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, double *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_DOUBLE, buf); } -int PIOc_get_varm_float (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], float *buf) +int PIOc_get_vars_ulonglong(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, + unsigned long long *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; + return PIOc_get_vars_tc(ncid, varid, start, count, stride, NC_UINT64, buf); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_FLOAT; - ibuftype = MPI_FLOAT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } +int PIOc_get_vara_text(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, char *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_CHAR, buf); +} +int PIOc_get_vara_uchar(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, unsigned char *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_UBYTE, buf); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_float(file->fh, varid,(size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_float(file->fh, varid,(size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_float(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_float_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +int PIOc_get_vara_schar(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, signed char *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_BYTE, buf); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +int PIOc_get_vara_ushort(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, unsigned short *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_USHORT, buf); +} - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } +int PIOc_get_vara_short(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, short *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_SHORT, buf); +} - return ierr; +int PIOc_get_vara_long(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, long *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_LONG, buf); } -int PIOc_get_var1_long (int ncid, int varid, const PIO_Offset index[], long *buf) +int PIOc_get_vara_uint(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, unsigned int *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_UINT, buf); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_LONG; - ibuftype = MPI_LONG; - ibufcnt = 1; - ierr = PIO_NOERR; +int PIOc_get_vara_int(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, int *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_INT, buf); +} - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } +int PIOc_get_vara_float(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, float *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_FLOAT, buf); +} +int PIOc_get_vara_double(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, double *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_DOUBLE, buf); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_long(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_long(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_long(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_long_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +int PIOc_get_vara_ulonglong(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, unsigned long long *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_UINT64, buf); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +int PIOc_get_vara_longlong(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, long long *buf) +{ + return PIOc_get_vars_tc(ncid, varid, start, count, NULL, NC_INT64, buf); +} - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } +int PIOc_get_var_text(int ncid, int varid, char *buf) +{ + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_CHAR, buf); +} - return ierr; +int PIOc_get_var_uchar(int ncid, int varid, unsigned char *buf) +{ + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_UBYTE, buf); } -int PIOc_get_varm_long (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], long *buf) +int PIOc_get_var_schar(int ncid, int varid, signed char *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_BYTE, buf); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_LONG; - ibuftype = MPI_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } +int PIOc_get_var_short(int ncid, int varid, short *buf) +{ + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_SHORT, buf); +} +int PIOc_get_var_uint (int ncid, int varid, unsigned int *buf) +{ + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_UINT, buf); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_long(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_long_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +int PIOc_get_var_int(int ncid, int varid, int *buf) +{ + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_INT, buf); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +int PIOc_get_var_long (int ncid, int varid, long *buf) +{ + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_LONG, buf); +} - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } +int PIOc_get_var_float(int ncid, int varid, float *buf) +{ + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_FLOAT, buf); +} - return ierr; +int PIOc_get_var_double(int ncid, int varid, double *buf) +{ + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_DOUBLE, buf); } -int PIOc_get_varm_ushort (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned short *buf) +int PIOc_get_var_ulonglong (int ncid, int varid, unsigned long long *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_UINT64, buf); +} + +int PIOc_get_var_longlong (int ncid, int varid, long long *buf) +{ + return PIOc_get_vars_tc(ncid, varid, NULL, NULL, NULL, NC_INT64, buf); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_USHORT; - ibuftype = MPI_UNSIGNED_SHORT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + /* Find the number of dimensions. */ + if ((ierr = PIOc_inq_varndims(ncid, varid, &ndims))) + return ierr; + /* Set up count array. */ + PIO_Offset count[ndims]; + for (int c = 0; c < ndims; c++) + count[c] = 1; - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_ushort(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_ushort_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } + return PIOc_get_vars_tc(ncid, varid, index, count, NULL, xtype, buf); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +int PIOc_get_var1_text(int ncid, int varid, const PIO_Offset *index, char *buf) +{ + return PIOc_get_var1_tc(ncid, varid, index, NC_CHAR, buf); +} - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } +int PIOc_get_var1_uchar (int ncid, int varid, const PIO_Offset *index, unsigned char *buf) +{ + return PIOc_get_var1_tc(ncid, varid, index, NC_UBYTE, buf); +} - return ierr; +int PIOc_get_var1_schar(int ncid, int varid, const PIO_Offset *index, signed char *buf) +{ + return PIOc_get_var1_tc(ncid, varid, index, NC_BYTE, buf); } -int PIOc_get_varm_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], long long *buf) +int PIOc_get_var1_ushort(int ncid, int varid, const PIO_Offset *index, unsigned short *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; + return PIOc_get_var1_tc(ncid, varid, index, NC_USHORT, buf); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_LONGLONG; - ibuftype = MPI_LONG_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } +int PIOc_get_var1_uint(int ncid, int varid, const PIO_Offset *index, unsigned int *buf) +{ + return PIOc_get_var1_tc(ncid, varid, index, NC_UINT, buf); +} +int PIOc_get_var1_long (int ncid, int varid, const PIO_Offset *index, long *buf) +{ + return PIOc_get_var1_tc(ncid, varid, index, NC_LONG, buf); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_longlong(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_longlong_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +int PIOc_get_var1_int(int ncid, int varid, const PIO_Offset *index, int *buf) +{ + return PIOc_get_var1_tc(ncid, varid, index, NC_INT, buf); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +int PIOc_get_var1_float(int ncid, int varid, const PIO_Offset *index, float *buf) +{ + return PIOc_get_var1_tc(ncid, varid, index, NC_FLOAT, buf); +} - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } +int PIOc_get_var1_double (int ncid, int varid, const PIO_Offset *index, double *buf) +{ + return PIOc_get_var1_tc(ncid, varid, index, NC_DOUBLE, buf); +} - return ierr; +int PIOc_get_var1_ulonglong (int ncid, int varid, const PIO_Offset *index, + unsigned long long *buf) +{ + return PIOc_get_var1_tc(ncid, varid, index, NC_INT64, buf); } + -int PIOc_get_vars_text (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], char *buf) +int PIOc_get_var1_longlong(int ncid, int varid, const PIO_Offset *index, + long long *buf) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; + return PIOc_get_var1_tc(ncid, varid, index, NC_INT64, buf); +} + +int PIOc_get_var (int ncid, int varid, void *buf, PIO_Offset bufcount, MPI_Datatype buftype) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS_TEXT; - ibuftype = MPI_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iiosystem; + msg = PIO_MSG_GET_VAR; + ibufcnt = bufcount; + ibuftype = buftype; + ierr = PIO_NOERR; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + if(ios->async_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } - if(ios->ioproc){ - switch(file->iotype){ + if(ios->ioproc){ + switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_var(file->fh, varid, buf);; + break; + case PIO_IOTYPE_NETCDF4C: #endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_var(file->fh, varid, buf);; + } + break; #endif #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: + case PIO_IOTYPE_PNETCDF: #ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars_text(file->fh, varid, start, count, stride, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_var(file->fh, varid, buf, bufcount, buftype);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; #else - ierr = ncmpi_get_vars_text_all(file->fh, varid, start, count, stride, buf);; + ierr = ncmpi_get_var_all(file->fh, varid, buf, bufcount, buftype);; #endif - break; + break; #endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } } - } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } - return ierr; + return ierr; } -int PIOc_get_var1_uchar (int ncid, int varid, const PIO_Offset index[], unsigned char *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR1_UCHAR; - ibuftype = MPI_UNSIGNED_CHAR; - ibufcnt = 1; - ierr = PIO_NOERR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var1_uchar(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var1_uchar(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var1_uchar(file->fh, varid, index, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_var1_uchar_all(file->fh, varid, index, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - return ierr; -} -int PIOc_get_vars (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], void *buf, PIO_Offset bufcount, MPI_Datatype buftype) +int PIOc_get_var1 (int ncid, int varid, const PIO_Offset *index, void *buf, PIO_Offset bufcount, MPI_Datatype buftype) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARS; - ibufcnt = bufcount; - ibuftype = buftype; - ierr = PIO_NOERR; + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VAR1; + ibufcnt = bufcount; + ibuftype = buftype; + ierr = PIO_NOERR; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + if(ios->async_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } - if(ios->ioproc){ - switch(file->iotype){ + if(ios->ioproc){ + switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_vars(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_var1(file->fh, varid, (size_t *) index, buf);; + break; + case PIO_IOTYPE_NETCDF4C: #endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_vars(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_var1(file->fh, varid, (size_t *) index, buf);; + } + break; #endif #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: + case PIO_IOTYPE_PNETCDF: #ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_vars(file->fh, varid, start, count, stride, buf, bufcount, buftype);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_var1(file->fh, varid, index, buf, bufcount, buftype);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; #else - ierr = ncmpi_get_vars_all(file->fh, varid, start, count, stride, buf, bufcount, buftype);; + ierr = ncmpi_get_var1_all(file->fh, varid, index, buf, bufcount, buftype);; #endif - break; + break; #endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } } - } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } - return ierr; + return ierr; } -int PIOc_get_varm_short (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], short *buf) +int PIOc_get_vara (int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, void *buf, PIO_Offset bufcount, MPI_Datatype buftype) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_SHORT; - ibuftype = MPI_SHORT; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iiosystem; + msg = PIO_MSG_GET_VARA; + ibufcnt = bufcount; + ibuftype = buftype; + ierr = PIO_NOERR; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + if(ios->async_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } - if(ios->ioproc){ - switch(file->iotype){ + if(ios->ioproc){ + switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_vara(file->fh, varid, (size_t *) start, (size_t *) count, buf);; + break; + case PIO_IOTYPE_NETCDF4C: #endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_vara(file->fh, varid, (size_t *) start, (size_t *) count, buf);; + } + break; #endif #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: + case PIO_IOTYPE_PNETCDF: #ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_short(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_vara(file->fh, varid, start, count, buf, bufcount, buftype);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; #else - ierr = ncmpi_get_varm_short_all(file->fh, varid, start, count, stride, imap, buf);; + ierr = ncmpi_get_vara_all(file->fh, varid, start, count, buf, bufcount, buftype);; #endif - break; + break; #endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } } - } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } - return ierr; + return ierr; } -int PIOc_get_varm_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned long long *buf) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VARM_ULONGLONG; - ibuftype = MPI_UNSIGNED_LONG_LONG; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - ibufcnt = 1; - for(int i=0;iasync_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_varm_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_varm_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: -#ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_varm_ulonglong(file->fh, varid, start, count, stride, imap, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; -#else - ierr = ncmpi_get_varm_ulonglong_all(file->fh, varid, start, count, stride, imap, buf);; -#endif - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } - return ierr; -} -int PIOc_get_var_schar (int ncid, int varid, signed char *buf) +int PIOc_get_vars (int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, const PIO_Offset *stride, void *buf, PIO_Offset bufcount, MPI_Datatype buftype) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - MPI_Datatype ibuftype; - int ndims; - int ibufcnt; - bool bcast = false; + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_VAR_SCHAR; - ibuftype = MPI_CHAR; - ierr = PIOc_inq_varndims(file->fh, varid, &ndims); - int dimid[ndims]; - PIO_Offset dimsize; - ibufcnt = 1; - PIOc_inq_vardimid(file->fh, varid, dimid); - for(int i=0;ifh, dimid[i], &dimsize); - ibufcnt *= dimsize; - } - ierr = PIO_NOERR; + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARS; + ibufcnt = bufcount; + ibuftype = buftype; + ierr = PIO_NOERR; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + if(ios->async_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } - if(ios->ioproc){ - switch(file->iotype){ + if(ios->ioproc){ + switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_var_schar(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_vars(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; + break; + case PIO_IOTYPE_NETCDF4C: #endif - case PIO_IOTYPE_NETCDF: - bcast = true; - if(ios->iomaster){ - ierr = nc_get_var_schar(file->fh, varid, buf);; - } - break; + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_vars(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; + } + break; #endif #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: + case PIO_IOTYPE_PNETCDF: #ifdef PNET_READ_AND_BCAST - ncmpi_begin_indep_data(file->fh); - if(ios->iomaster){ - ierr = ncmpi_get_var_schar(file->fh, varid, buf);; - }; - ncmpi_end_indep_data(file->fh); - bcast=true; + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_vars(file->fh, varid, start, count, stride, buf, bufcount, buftype);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; #else - ierr = ncmpi_get_var_schar_all(file->fh, varid, buf);; + ierr = ncmpi_get_vars_all(file->fh, varid, start, count, stride, buf, bufcount, buftype);; #endif - break; + break; #endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } } - } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - if(ios->async_interface || bcast || - (ios->num_iotasks < ios->num_comptasks)){ - MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); - } + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } - return ierr; + return ierr; } diff --git a/src/clib/pio_internal.h b/src/clib/pio_internal.h index 740b8fdf1a6d..412b3d990557 100644 --- a/src/clib/pio_internal.h +++ b/src/clib/pio_internal.h @@ -17,6 +17,12 @@ #include #endif +#ifdef PIO_ENABLE_LOGGING +void pio_log(int severity, const char *fmt, ...); +#define LOG(e) pio_log e +#else +#define LOG(e) +#endif /* PIO_ENABLE_LOGGING */ #define max(a,b) \ ({ __typeof__ (a) _a = (a); \ @@ -146,6 +152,8 @@ typedef struct pio_swapm_defaults void flush_buffer(int ncid, wmulti_buffer *wmb, bool flushtodisk); void piomemerror(iosystem_desc_t ios, size_t req, char *fname, const int line); void compute_maxaggregate_bytes(const iosystem_desc_t ios, io_desc_t *iodesc); + int check_mpi(file_desc_t *file, const int mpierr, const char *filename, + const int line); #ifdef BGQ void identity(MPI_Comm comm, int *iotask); @@ -166,15 +174,12 @@ enum PIO_MSG{ PIO_MSG_INQ_ATT, PIO_MSG_INQ_FORMAT, PIO_MSG_INQ_VARID, - PIO_MSG_INQ_VARNATTS, PIO_MSG_DEF_VAR, PIO_MSG_INQ_VAR, - PIO_MSG_INQ_VARNAME, PIO_MSG_PUT_ATT_DOUBLE, PIO_MSG_PUT_ATT_INT, PIO_MSG_RENAME_ATT, PIO_MSG_DEL_ATT, - PIO_MSG_INQ_NATTS, PIO_MSG_INQ, PIO_MSG_GET_ATT_TEXT, PIO_MSG_GET_ATT_SHORT, @@ -189,21 +194,14 @@ enum PIO_MSG{ PIO_MSG_GET_ATT_ULONGLONG, PIO_MSG_GET_ATT_USHORT, PIO_MSG_PUT_ATT_ULONGLONG, - PIO_MSG_INQ_DIMLEN, PIO_MSG_GET_ATT_UINT, PIO_MSG_GET_ATT_LONGLONG, PIO_MSG_PUT_ATT_SCHAR, PIO_MSG_PUT_ATT_FLOAT, - PIO_MSG_INQ_NVARS, PIO_MSG_RENAME_DIM, - PIO_MSG_INQ_VARNDIMS, PIO_MSG_GET_ATT_LONG, PIO_MSG_INQ_DIM, PIO_MSG_INQ_DIMID, - PIO_MSG_INQ_UNLIMDIM, - PIO_MSG_INQ_VARDIMID, - PIO_MSG_INQ_ATTLEN, - PIO_MSG_INQ_DIMNAME, PIO_MSG_PUT_ATT_USHORT, PIO_MSG_GET_ATT_FLOAT, PIO_MSG_SYNC, @@ -212,11 +210,8 @@ enum PIO_MSG{ PIO_MSG_GET_ATT_SCHAR, PIO_MSG_INQ_ATTID, PIO_MSG_DEF_DIM, - PIO_MSG_INQ_NDIMS, - PIO_MSG_INQ_VARTYPE, PIO_MSG_GET_ATT_INT, PIO_MSG_GET_ATT_DOUBLE, - PIO_MSG_INQ_ATTTYPE, PIO_MSG_PUT_ATT_UCHAR, PIO_MSG_GET_ATT_UCHAR, PIO_MSG_PUT_VARS_UCHAR, @@ -375,7 +370,10 @@ enum PIO_MSG{ PIO_MSG_FREEDECOMP, PIO_MSG_CLOSE_FILE, PIO_MSG_DELETE_FILE, - PIO_MSG_EXIT + PIO_MSG_EXIT, + PIO_MSG_GET_ATT, + PIO_MSG_PUT_ATT, + PIO_MSG_INQ_TYPE }; #endif diff --git a/src/clib/pio_msg.c b/src/clib/pio_msg.c new file mode 100644 index 000000000000..be5c2676f7bf --- /dev/null +++ b/src/clib/pio_msg.c @@ -0,0 +1,2179 @@ +/** + * @file + * @author Ed Hartnett + * @date 2016 + * @brief PIO async msg handling + * + * @see http://code.google.com/p/parallelio/ + */ + +#include +#include +#include + +#ifdef PIO_ENABLE_LOGGING +extern int my_rank; +extern int pio_log_level; +#endif /* PIO_ENABLE_LOGGING */ + +/** This function is run on the IO tasks to find netCDF type + * length. */ +int inq_type_handler(iosystem_desc_t *ios) +{ + int ncid; + int xtype; + char name_present, size_present; + char *namep = NULL, name[NC_MAX_NAME + 1]; + PIO_Offset *sizep = NULL, size; + int mpierr; + int ret; + + LOG((1, "inq_type_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&xtype, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&size_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + + /* Handle null pointer issues. */ + if (name_present) + namep = name; + if (size_present) + sizep = &size; + + /* Call the function. */ + if ((ret = PIOc_inq_type(ncid, xtype, namep, sizep))) + return ret; + + LOG((1, "inq_type_handler succeeded!")); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to find netCDF file + * format. */ +int inq_format_handler(iosystem_desc_t *ios) +{ + int ncid; + int *formatp = NULL, format; + char format_present; + int mpierr; + int ret; + + LOG((1, "inq_format_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&format_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "inq_format_handler got parameters ncid = %d format_present = %d", + ncid, format_present)); + + /* Manage NULL pointers. */ + if (format_present) + formatp = &format; + + /* Call the function. */ + if ((ret = PIOc_inq_format(ncid, formatp))) + return ret; + + if (formatp) + LOG((2, "inq_format_handler format = %d", *formatp)); + LOG((1, "inq_format_handler succeeded!")); + + return PIO_NOERR; +} + +/** This function is run on the IO tasks to create a netCDF file. */ +int create_file_handler(iosystem_desc_t *ios) +{ + int ncid; + int len; + int iotype; + char *filename; + int mode; + int mpierr; + int ret; + + LOG((1, "create_file_handler comproot = %d\n", ios->comproot)); + + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&len, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "create_file_handler got parameter len = %d\n", len)); + if (!(filename = malloc(len + 1 * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)filename, len + 1, MPI_CHAR, 0, + ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&iotype, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&mode, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "create_file_handler got parameters len = %d " + "filename = %s iotype = %d mode = %d\n", + len, filename, iotype, mode)); + + /* Call the create file function. */ + if ((ret = PIOc_createfile(ios->iosysid, &ncid, &iotype, filename, mode))) + return ret; + + /* Free resources. */ + free(filename); + + LOG((1, "create_file_handler succeeded!")); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to close a netCDF file. It is + * only ever run on the IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @return PIO_NOERR for success, error code otherwise. +*/ +int close_file_handler(iosystem_desc_t *ios) +{ + int ncid; + int mpierr; + int ret; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d close_file_handler\n", my_rank)); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "%d create_file_handler got parameter ncid = %d\n", ncid)); + + /* Call the close file function. */ + if ((ret = PIOc_closefile(ncid))) + return ret; + + LOG((1, "close_file_handler succeeded!\n", my_rank)); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to inq a netCDF file. It is + * only ever run on the IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @return PIO_NOERR for success, error code otherwise. +*/ +int inq_handler(iosystem_desc_t *ios) +{ + int ncid; + int ndims, nvars, ngatts, unlimdimid; + int *ndimsp = NULL, *nvarsp = NULL, *ngattsp = NULL, *unlimdimidp = NULL; + char ndims_present, nvars_present, ngatts_present, unlimdimid_present; + int mpierr; + int ret; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d inq_handler\n", my_rank)); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&ndims_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&nvars_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&ngatts_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&unlimdimid_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "%d inq_handler ndims_present = %d nvars_present = %d ngatts_present = %d unlimdimid_present = %d\n", + ndims_present, nvars_present, ngatts_present, unlimdimid_present)); + + /* NULLs passed in to any of the pointers in the original call + * need to be matched with NULLs here. Assign pointers where + * non-NULL pointers were passed in. */ + if (ndims_present) + ndimsp = &ndims; + if (nvars_present) + nvarsp = &nvars; + if (ngatts_present) + ngattsp = &ngatts; + if (unlimdimid_present) + unlimdimidp = &unlimdimid; + + /* Call the inq function to get the values. */ + if ((ret = PIOc_inq(ncid, ndimsp, nvarsp, ngattsp, unlimdimidp))) + return ret; + + return PIO_NOERR; +} + +/** Do an inq_dim on a netCDF dimension. This function is only run on + * IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @param msg the message sent my the comp root task. + * @return PIO_NOERR for success, error code otherwise. +*/ +int inq_dim_handler(iosystem_desc_t *ios, int msg) +{ + int ncid; + int dimid; + char name_present, len_present; + char *dimnamep = NULL; + PIO_Offset *dimlenp = NULL; + char dimname[NC_MAX_NAME + 1]; + PIO_Offset dimlen; + + int mpierr; + int ret; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "inq_dim_handler\n", my_rank)); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&dimid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&len_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + printf("%d inq_handler name_present = %d len_present = %d\n", + name_present, len_present); + + /* Set the non-null pointers. */ + if (name_present) + dimnamep = dimname; + if (len_present) + dimlenp = &dimlen; + + /* Call the inq function to get the values. */ + if ((ret = PIOc_inq_dim(ncid, dimid, dimnamep, dimlenp))) + return ret; + + return PIO_NOERR; +} + +/** Do an inq_dimid on a netCDF dimension name. This function is only + * run on IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @return PIO_NOERR for success, error code otherwise. +*/ +int inq_dimid_handler(iosystem_desc_t *ios) +{ + int ncid; + int *dimidp = NULL, dimid; + int mpierr; + int id_present; + int ret; + int namelen; + char *name; + + LOG((1, "inq_dimid_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(name = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&id_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "inq_dimid_handler ncid = %d namelen = %d name = %s id_present = %d", + ncid, namelen, name, id_present)); + + /* Set non-null pointer. */ + if (id_present) + dimidp = &dimid; + + /* Call the inq_dimid function. */ + if ((ret = PIOc_inq_dimid(ncid, name, dimidp))) + return ret; + + /* Free resources. */ + free(name); + + return PIO_NOERR; +} + +/** Handle attribute inquiry operations. This code only runs on IO + * tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @param msg the message sent my the comp root task. + * @return PIO_NOERR for success, error code otherwise. +*/ +int inq_att_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int mpierr; + int ret; + char *name5; + int namelen; + int *op, *ip; + nc_type xtype, *xtypep = NULL; + PIO_Offset len, *lenp = NULL; + char xtype_present, len_present; + + LOG((1, "inq_att_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm))) + return PIO_EIO; + if (!(name5 = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)name5, namelen + 1, MPI_CHAR, ios->compmaster, + ios->intercomm))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast(&xtype_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&len_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + + /* Match NULLs in collective function call. */ + if (xtype_present) + xtypep = &xtype; + if (len_present) + lenp = &len; + + /* Call the function to learn about the attribute. */ + if ((ret = PIOc_inq_att(ncid, varid, name5, xtypep, lenp))) + return ret; + + return PIO_NOERR; +} + +/** Handle attribute inquiry operations. This code only runs on IO + * tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @param msg the message sent my the comp root task. + * @return PIO_NOERR for success, error code otherwise. +*/ +int inq_attname_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int attnum; + char name[NC_MAX_NAME + 1], *namep = NULL; + char name_present; + int mpierr; + int ret; + + LOG((1, "inq_att_name_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&attnum, 1, MPI_INT, ios->compmaster, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "inq_attname_handler got ncid = %d varid = %d attnum = %d name_present = %d", + ncid, varid, attnum, name_present)); + + /* Match NULLs in collective function call. */ + if (name_present) + namep = name; + + /* Call the function to learn about the attribute. */ + if ((ret = PIOc_inq_attname(ncid, varid, attnum, namep))) + return ret; + + return PIO_NOERR; +} + +/** Handle attribute inquiry operations. This code only runs on IO + * tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @param msg the message sent my the comp root task. + * @return PIO_NOERR for success, error code otherwise. +*/ +int inq_attid_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int attnum; + char *name; + int namelen; + int id, *idp = NULL; + char id_present; + int mpierr; + int ret; + + LOG((1, "inq_attid_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm))) + return PIO_EIO; + if (!(name = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast(name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&id_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "inq_attid_handler got ncid = %d varid = %d attnum = %d id_present = %d", + ncid, varid, attnum, id_present)); + + /* Match NULLs in collective function call. */ + if (id_present) + idp = &id; + + /* Call the function to learn about the attribute. */ + if ((ret = PIOc_inq_attid(ncid, varid, name, idp))) + return ret; + + /* Free resources. */ + free(name); + + return PIO_NOERR; +} + +/** Handle attribute operations. This code only runs on IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @param msg the message sent my the comp root task. + * @return PIO_NOERR for success, error code otherwise. +*/ +int att_put_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int mpierr; + int ierr; + char *name; + int namelen; + PIO_Offset attlen, typelen; + nc_type atttype; + int *op, *ip; + int iotype; + + LOG((1, "att_put_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!(name = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, + ios->intercomm); + if ((mpierr = MPI_Bcast(&atttype, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&attlen, 1, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + if (!(op = malloc(attlen * typelen))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)op, attlen * typelen, MPI_BYTE, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "att_put_handler ncid = %d varid = %d namelen = %d name = %s iotype = %d" + "atttype = %d attlen = %d typelen = %d", + ncid, varid, namelen, name, iotype, atttype, attlen, typelen)); + + /* Call the function to read the attribute. */ + if ((ierr = PIOc_put_att(ncid, varid, name, atttype, attlen, op))) + return ierr; + + /* Free resources. */ + free(name); + free(op); + + return PIO_NOERR; +} + +/** Handle attribute operations. This code only runs on IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @param msg the message sent my the comp root task. + * @return PIO_NOERR for success, error code otherwise. +*/ +int att_get_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int mpierr; + int ierr; + char *name; + int namelen; + PIO_Offset attlen, typelen; + nc_type atttype; + int *op, *ip; + int iotype; + + LOG((1, "att_get_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!(name = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, + ios->intercomm); + if ((mpierr = MPI_Bcast(&iotype, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&atttype, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&attlen, 1, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "att_get_handler ncid = %d varid = %d namelen = %d name = %s iotype = %d" + "atttype = %d attlen = %d typelen = %d", + ncid, varid, namelen, name, iotype, atttype, attlen, typelen)); + + /* Allocate space for the attribute data. */ + if (!(ip = malloc(attlen * typelen))) + return PIO_ENOMEM; + + /* Call the function to read the attribute. */ + if ((ierr = PIOc_get_att(ncid, varid, name, ip))) + return ierr; + + /* Free resources. */ + free(name); + free(ip); + + return PIO_NOERR; +} + +/** Handle var put operations. This code only runs on IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @return PIO_NOERR for success, error code otherwise. +*/ +int put_vars_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int mpierr; + int ierr; + char *name; + int namelen; + PIO_Offset typelen; /** Length (in bytes) of this type. */ + nc_type xtype; /** Type of the data being written. */ + char start_present, count_present, stride_present; + PIO_Offset *startp = NULL, *countp = NULL, *stridep = NULL; + int ndims; /** Number of dimensions. */ + void *buf; /** Buffer for data storage. */ + size_t num_elem; /** Number of data elements in the buffer. */ + + LOG((1, "put_vars_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&ndims, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + + /* Now we know how big to make these arrays. */ + PIO_Offset start[ndims], count[ndims], stride[ndims]; + + if ((mpierr = MPI_Bcast(&start_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if (!mpierr && start_present) + { + if ((mpierr = MPI_Bcast(start, ndims, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "put_vars_handler getting start[0] = %d ndims = %d", start[0], ndims)); + } + if ((mpierr = MPI_Bcast(&count_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if (!mpierr && count_present) + if ((mpierr = MPI_Bcast(count, ndims, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&stride_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if (!mpierr && stride_present) + if ((mpierr = MPI_Bcast(stride, ndims, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&xtype, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&num_elem, 1, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "put_vars_handler ncid = %d varid = %d ndims = %d start_present = %d " + "count_present = %d stride_present = %d xtype = %d num_elem = %d typelen = %d", + ncid, varid, ndims, start_present, count_present, stride_present, xtype, + num_elem, typelen)); + + for (int d = 0; d < ndims; d++) + { + if (start_present) + LOG((2, "start[%d] = %d\n", d, start[d])); + if (count_present) + LOG((2, "count[%d] = %d\n", d, count[d])); + if (stride_present) + LOG((2, "stride[%d] = %d\n", d, stride[d])); + } + + /* Allocate room for our data. */ + if (!(buf = malloc(num_elem * typelen))) + return PIO_ENOMEM; + + /* Get the data. */ + if ((mpierr = MPI_Bcast(buf, num_elem * typelen, MPI_BYTE, 0, ios->intercomm))) + return PIO_EIO; + + for (int e = 0; e < num_elem; e++) + LOG((2, "element %d = %d", e, ((int *)buf)[e])); + + /* Set the non-NULL pointers. */ + if (start_present) + startp = start; + if (count_present) + countp = count; + if (stride_present) + stridep = stride; + + /* Call the function to write the data. */ + switch(xtype) + { + case NC_BYTE: + ierr = PIOc_put_vars_schar(ncid, varid, startp, countp, stridep, buf); + break; + case NC_CHAR: + ierr = PIOc_put_vars_schar(ncid, varid, startp, countp, stridep, buf); + break; + case NC_SHORT: + ierr = PIOc_put_vars_short(ncid, varid, startp, countp, stridep, buf); + break; + case NC_INT: + ierr = PIOc_put_vars_int(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_FLOAT: + ierr = PIOc_put_vars_float(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_DOUBLE: + ierr = PIOc_put_vars_double(ncid, varid, startp, countp, + stridep, buf); + break; +#ifdef _NETCDF4 + case NC_UBYTE: + ierr = PIOc_put_vars_uchar(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_USHORT: + ierr = PIOc_put_vars_ushort(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_UINT: + ierr = PIOc_put_vars_uint(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_INT64: + ierr = PIOc_put_vars_longlong(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_UINT64: + ierr = PIOc_put_vars_ulonglong(ncid, varid, startp, countp, + stridep, buf); + break; + /* case NC_STRING: */ + /* ierr = PIOc_put_vars_string(ncid, varid, startp, countp, */ + /* stridep, (void *)buf); */ + /* break; */ + /* default:*/ + /* ierr = PIOc_put_vars(ncid, varid, startp, countp, */ + /* stridep, buf); */ +#endif /* _NETCDF4 */ + } + + return PIO_NOERR; +} + +/** Handle var get operations. This code only runs on IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @return PIO_NOERR for success, error code otherwise. +*/ +int get_vars_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int mpierr; + int ierr; + char *name; + int namelen; + PIO_Offset typelen; /** Length (in bytes) of this type. */ + nc_type xtype; /** Type of the data being written. */ + char start_present, count_present, stride_present; + PIO_Offset *startp = NULL, *countp = NULL, *stridep = NULL; + int ndims; /** Number of dimensions. */ + void *buf; /** Buffer for data storage. */ + size_t num_elem; /** Number of data elements in the buffer. */ + + LOG((1, "get_vars_handler")); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&ndims, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + + /* Now we know how big to make these arrays. */ + PIO_Offset start[ndims], count[ndims], stride[ndims]; + + if ((mpierr = MPI_Bcast(&start_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if (!mpierr && start_present) + { + if ((mpierr = MPI_Bcast(start, ndims, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "put_vars_handler getting start[0] = %d ndims = %d", start[0], ndims)); + } + if ((mpierr = MPI_Bcast(&count_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if (!mpierr && count_present) + if ((mpierr = MPI_Bcast(count, ndims, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&stride_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if (!mpierr && stride_present) + if ((mpierr = MPI_Bcast(stride, ndims, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&xtype, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&num_elem, 1, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "get_vars_handler ncid = %d varid = %d ndims = %d start_present = %d " + "count_present = %d stride_present = %d xtype = %d num_elem = %d typelen = %d", + ncid, varid, ndims, start_present, count_present, stride_present, xtype, + num_elem, typelen)); + + for (int d = 0; d < ndims; d++) + { + if (start_present) + LOG((2, "start[%d] = %d\n", d, start[d])); + if (count_present) + LOG((2, "count[%d] = %d\n", d, count[d])); + if (stride_present) + LOG((2, "stride[%d] = %d\n", d, stride[d])); + } + + /* Allocate room for our data. */ + if (!(buf = malloc(num_elem * typelen))) + return PIO_ENOMEM; + + /* Set the non-NULL pointers. */ + if (start_present) + startp = start; + if (count_present) + countp = count; + if (stride_present) + stridep = stride; + + /* Call the function to read the data. */ + switch(xtype) + { + case NC_BYTE: + ierr = PIOc_get_vars_schar(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_CHAR: + ierr = PIOc_get_vars_schar(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_SHORT: + ierr = PIOc_get_vars_short(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_INT: + ierr = PIOc_get_vars_int(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_FLOAT: + ierr = PIOc_get_vars_float(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_DOUBLE: + ierr = PIOc_get_vars_double(ncid, varid, startp, countp, + stridep, buf); + break; +#ifdef _NETCDF4 + case NC_UBYTE: + ierr = PIOc_get_vars_uchar(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_USHORT: + ierr = PIOc_get_vars_ushort(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_UINT: + ierr = PIOc_get_vars_uint(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_INT64: + ierr = PIOc_get_vars_longlong(ncid, varid, startp, countp, + stridep, buf); + break; + case NC_UINT64: + ierr = PIOc_get_vars_ulonglong(ncid, varid, startp, countp, + stridep, buf); + break; + /* case NC_STRING: */ + /* ierr = PIOc_get_vars_string(ncid, varid, startp, countp, */ + /* stridep, (void *)buf); */ + /* break; */ + /* default:*/ + /* ierr = PIOc_get_vars(ncid, varid, startp, countp, */ + /* stridep, buf); */ +#endif /* _NETCDF4 */ + } + + LOG((1, "get_vars_handler succeeded!")); + return PIO_NOERR; +} + +/** Do an inq_var on a netCDF variable. This function is only run on + * IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @param msg the message sent my the comp root task. + * @return PIO_NOERR for success, error code otherwise. +*/ +int inq_var_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int mpierr; + char name_present, xtype_present, ndims_present, dimids_present, natts_present; + char name[NC_MAX_NAME + 1], *namep; + nc_type xtype, *xtypep = NULL; + int *ndimsp = NULL, *dimidsp = NULL, *nattsp = NULL; + int ndims, dimids[NC_MAX_DIMS], natts; + int ret; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d inq_var_handler\n", my_rank)); + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&xtype_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&ndims_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&dimids_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&natts_present, 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + printf("%d inq_var_handler ncid = %d varid = %d name_present = %d xtype_present = %d ndims_present = %d " + "dimids_present = %d natts_present = %d\n", + my_rank, ncid, varid, name_present, xtype_present, ndims_present, dimids_present, natts_present); + + /* Set the non-NULL pointers. */ + if (name_present) + namep = name; + if (xtype_present) + xtypep = &xtype; + if (ndims_present) + ndimsp = &ndims; + if (dimids_present) + dimidsp = dimids; + if (natts_present) + nattsp = &natts; + + /* Call the inq function to get the values. */ + if ((ret = PIOc_inq_var(ncid, varid, namep, xtypep, ndimsp, dimidsp, nattsp))) + return ret; + + return PIO_NOERR; +} + +/** Do an inq_varid on a netCDF variable name. This function is only + * run on IO tasks. + * + * @param ios pointer to the iosystem_desc_t. + * @return PIO_NOERR for success, error code otherwise. +*/ +int inq_varid_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int mpierr; + int ret; + int namelen; + char *name; + + /* Get the parameters for this function that the the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(name = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + + /* Call the inq_dimid function. */ + if ((ret = PIOc_inq_varid(ncid, name, &varid))) + return ret; + + /* Free resources. */ + free(name); + + return PIO_NOERR; +} + +/** This function is run on the IO tasks to sync a netCDF file. + * + * @param ios pointer to the iosystem_desc_t. + * @return PIO_NOERR for success, error code otherwise. +*/ +int sync_file_handler(iosystem_desc_t *ios) +{ + int ncid; + int mpierr; + int ret; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d sync_file_handler\n", my_rank)); + + /* Get the parameters for this function that the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "%d sync_file_handler got parameter ncid = %d\n", my_rank, ncid)); + + /* Call the sync file function. */ + if ((ret = PIOc_sync(ncid))) + return ret; + + LOG((2, "sync_file_handler succeeded!")); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to enddef a netCDF file. + * + * @param ios pointer to the iosystem_desc_t. + * @return PIO_NOERR for success, error code otherwise. +*/ +int change_def_file_handler(iosystem_desc_t *ios, int msg) +{ + int ncid; + int mpierr; + int ret; + + LOG((1, "change_def_file_handler")); + + /* Get the parameters for this function that the comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + + /* Call the function. */ + ret = (msg == PIO_MSG_ENDDEF) ? PIOc_enddef(ncid) : PIOc_redef(ncid); + + LOG((1, "change_def_file_handler succeeded!")); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to define a netCDF + * variable. */ +int def_var_handler(iosystem_desc_t *ios) +{ + int ncid; + int len, namelen; + int iotype; + char *name; + int mode; + int mpierr; + int ret; + int varid; + nc_type xtype; + int ndims; + int *dimids; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d def_var_handler comproot = %d\n", my_rank, ios->comproot)); + + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(name = malloc(namelen + 1 * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, 0, + ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&xtype, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&ndims, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(dimids = malloc(ndims * sizeof(int)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast(dimids, ndims, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + LOG((1, "%d def_var_handler got parameters namelen = %d " + "name = %s len = %d ncid = %d\n", + my_rank, namelen, name, len, ncid)); + + /* Call the create file function. */ + if ((ret = PIOc_def_var(ncid, name, xtype, ndims, dimids, &varid))) + return ret; + + /* Free resources. */ + free(name); + free(dimids); + + LOG((1, "%d def_var_handler succeeded!\n", my_rank)); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to define a netCDF + * dimension. */ +int def_dim_handler(iosystem_desc_t *ios) +{ + int ncid; + int len, namelen; + int iotype; + char *name; + int mode; + int mpierr; + int ret; + int dimid; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "def_dim_handler comproot = %d", ios->comproot)); + + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(name = malloc(namelen + 1 * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, 0, + ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&len, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "def_dim_handler got parameters namelen = %d " + "name = %s len = %d ncid = %d", namelen, name, len, ncid)); + + /* Call the create file function. */ + if ((ret = PIOc_def_dim(ncid, name, len, &dimid))) + return ret; + + /* Free resources. */ + free(name); + + LOG((1, "%d def_dim_handler succeeded!\n", my_rank)); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to rename a netCDF + * dimension. */ +int rename_dim_handler(iosystem_desc_t *ios) +{ + int ncid; + int len, namelen; + int iotype; + char *name; + int mode; + int mpierr; + int ret; + int dimid; + char name1[NC_MAX_NAME + 1]; + + LOG((1, "rename_dim_handler")); + + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&dimid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(name = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "rename_dim_handler got parameters namelen = %d " + "name = %s ncid = %d dimid = %d", namelen, name, ncid, dimid)); + + /* Call the create file function. */ + if ((ret = PIOc_rename_dim(ncid, dimid, name))) + return ret; + + /* Free resources. */ + free(name); + + LOG((1, "%d rename_dim_handler succeeded!\n", my_rank)); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to rename a netCDF + * dimension. */ +int rename_var_handler(iosystem_desc_t *ios) +{ + int ncid; + int len, namelen; + int iotype; + char *name; + int mode; + int mpierr; + int ret; + int varid; + char name1[NC_MAX_NAME + 1]; + + LOG((1, "rename_var_handler")); + + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(name = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "rename_var_handler got parameters namelen = %d " + "name = %s ncid = %d varid = %d", namelen, name, ncid, varid)); + + /* Call the create file function. */ + if ((ret = PIOc_rename_var(ncid, varid, name))) + return ret; + + /* Free resources. */ + free(name); + + LOG((1, "%d rename_var_handler succeeded!\n", my_rank)); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to rename a netCDF + * attribute. */ +int rename_att_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int namelen, newnamelen; + char *name, *newname; + int mpierr; + int ret; + + LOG((1, "rename_att_handler")); + + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(name = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast(name, namelen + 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&newnamelen, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(newname = malloc((newnamelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast(newname, newnamelen + 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "rename_att_handler got parameters namelen = %d name = %s ncid = %d varid = %d " + "newnamelen = %d newname = %s", namelen, name, ncid, varid, newnamelen, newname)); + + /* Call the create file function. */ + if ((ret = PIOc_rename_att(ncid, varid, name, newname))) + return ret; + + /* Free resources. */ + free(name); + free(newname); + + LOG((1, "%d rename_att_handler succeeded!\n", my_rank)); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to delete a netCDF + * attribute. */ +int delete_att_handler(iosystem_desc_t *ios) +{ + int ncid; + int varid; + int namelen, newnamelen; + char *name, *newname; + int mpierr; + int ret; + + LOG((1, "delete_att_handler")); + + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(name = malloc((namelen + 1) * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast(name, namelen + 1, MPI_CHAR, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "delete_att_handler namelen = %d name = %s ncid = %d varid = %d ", + namelen, name, ncid, varid)); + + /* Call the create file function. */ + if ((ret = PIOc_del_att(ncid, varid, name))) + return ret; + + /* Free resources. */ + free(name); + + LOG((1, "delete_att_handler succeeded!")); + return PIO_NOERR; +} + +/** This function is run on the IO tasks. It reads or writes an array + * of data to a netCDF variable. + * + * @param ios pointer to the iosystem_desc_t data. + * @param msg the message sent my the comp root task. + * + * @return PIO_NOERR for success, error code otherwise. */ +int vara_handler(iosystem_desc_t *ios, int msg) +{ + int ncid; + int len, namelen; + int iotype; + char *name; + int mode; + int mpierr; + int ret; + int varid; + nc_type xtype; + int ndims; + int *dimids; + void *data; + int size_in_bytes; + PIO_Offset *count, *start; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d def_var_handler comproot = %d\n", my_rank, ios->comproot)); + + if (msg == PIO_MSG_PUT_VARA) + { + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&ncid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&varid, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((ret = PIOc_inq_varndims(ncid, varid, &ndims))) + return ret; + if (!(start = malloc(ndims * sizeof(int)))) + return PIO_ENOMEM; + if (!(count = malloc(ndims * sizeof(int)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast(start, ndims, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(count, ndims, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + int size = 1; + for (int d = 0; d < ndims; d++) + size *= count[d]; + size_in_bytes = size * sizeof(int); + if (!(data = malloc(size_in_bytes))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast(data, size_in_bytes, MPI_INT, 0, + ios->intercomm))) + return PIO_EIO; + LOG((2, " def_var_handler got parameters namelen = %d " + "name = %s len = %d ncid = %d", namelen, name, len, ncid)); + + /* Call the create file function. */ + if ((ret = PIOc_put_vara_int(ncid, varid, start, count, data))) + return ret; + + /* Free resources. */ + free(start); + free(count); + free(data); + } + else + { + + } + + LOG((1, "%d vara_handler succeeded!\n", my_rank)); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to open a netCDF file. + * + * @param ios pointer to the iosystem_desc_t data. + * + * @return PIO_NOERR for success, error code otherwise. */ +int open_file_handler(iosystem_desc_t *ios) +{ + int ncid; + int len; + int iotype; + char *filename; + int mode; + int mpierr; + int ret; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d open_file_handler comproot = %d\n", my_rank, ios->comproot)); + + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&len, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "open_file_handler got parameter len = %d", len)); + if (!(filename = malloc(len + 1 * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)filename, len + 1, MPI_CHAR, 0, + ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&iotype, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if ((mpierr = MPI_Bcast(&mode, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + LOG((2, "open_file_handler got parameters len = %d filename = %s iotype = %d mode = %d\n", + len, filename, iotype, mode)); + + /* Call the open file function. */ + if ((ret = PIOc_openfile(ios->iosysid, &ncid, &iotype, filename, mode))) + return ret; + + /* Free resources. */ + free(filename); + + LOG((1, "%d open_file_handler succeeded!\n", my_rank)); + return PIO_NOERR; +} + +/** This function is run on the IO tasks to delete a netCDF file. + * + * @param ios pointer to the iosystem_desc_t data. + * + * @return PIO_NOERR for success, error code otherwise. */ +int delete_file_handler(iosystem_desc_t *ios) +{ + int ncid; + int len; + char *filename; + int mpierr; + int ret; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d delete_file_handler comproot = %d\n", my_rank, ios->comproot)); + + /* Get the parameters for this function that the he comp master + * task is broadcasting. */ + if ((mpierr = MPI_Bcast(&len, 1, MPI_INT, 0, ios->intercomm))) + return PIO_EIO; + if (!(filename = malloc(len + 1 * sizeof(char)))) + return PIO_ENOMEM; + if ((mpierr = MPI_Bcast((void *)filename, len + 1, MPI_CHAR, 0, + ios->intercomm))) + return PIO_EIO; + LOG((1, "%d delete_file_handler got parameters len = %d filename = %s\n", + my_rank, len, filename)); + + /* Call the delete file function. */ + if ((ret = PIOc_deletefile(ios->iosysid, filename))) + return ret; + + /* Free resources. */ + free(filename); + + LOG((1, "%d delete_file_handler succeeded!\n", my_rank)); + return PIO_NOERR; +} + +int initdecomp_dof_handler(iosystem_desc_t *ios) +{ + return PIO_NOERR; +} + +int writedarray_handler(iosystem_desc_t *ios) +{ + return PIO_NOERR; +} + +int readdarray_handler(iosystem_desc_t *ios) +{ + return PIO_NOERR; +} + +int seterrorhandling_handler(iosystem_desc_t *ios) +{ + return PIO_NOERR; +} + +int var_handler(iosystem_desc_t *ios, int msg) +{ + return PIO_NOERR; +} + +int freedecomp_handler(iosystem_desc_t *ios) +{ + return PIO_NOERR; +} + +int finalize_handler(iosystem_desc_t *ios) +{ + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d finalize_handler called\n", my_rank)); + return PIO_NOERR; +} + +int pio_callback_handler(iosystem_desc_t *ios, int msg) +{ + return PIO_NOERR; +} + +/** This function is called by the IO tasks. This function will not + return, unless there is an error. */ +int pio_msg_handler(int io_rank, int component_count, iosystem_desc_t *iosys) +{ + iosystem_desc_t *my_iosys; + int msg = 0; + MPI_Request req[component_count]; + MPI_Status status; + int index; + int mpierr; + int ret; + + int my_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + LOG((1, "%d pio_msg_handler called\n", my_rank)); + + /* Have IO comm rank 0 (the ioroot) register to receive + * (non-blocking) for a message from each of the comproots. */ + if (!io_rank) + { + for (int cmp = 0; cmp < component_count; cmp++) + { + my_iosys = &iosys[cmp]; + LOG((1, "%d about to call MPI_Irecv\n", my_rank)); + mpierr = MPI_Irecv(&msg, 1, MPI_INT, my_iosys->comproot, MPI_ANY_TAG, + my_iosys->union_comm, &req[cmp]); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + } + } + + /* If the message is not -1, keep processing messages. */ + while (msg != -1) + { + /* Wait until any one of the requests are complete. */ + if (!io_rank) + { + LOG((1, "%d about to call MPI_Waitany req[0] = %d MPI_REQUEST_NULL = %d\n", + my_rank, req[0], MPI_REQUEST_NULL)); + mpierr = MPI_Waitany(component_count, req, &index, &status); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + LOG((3, "Waitany returned index = %d req[%d] = %d", + index, index, req[index])); + } + + /* Broadcast the index of the computational component that + * originated the request to the rest of the IO tasks. */ + mpierr = MPI_Bcast(&index, 1, MPI_INT, 0, iosys->io_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + my_iosys = &iosys[index]; + LOG((3, "index MPI_Bcast complete index = %d", index)); + + /* Broadcast the msg value to the rest of the IO tasks. */ + LOG((3, "about to call msg MPI_Bcast")); + mpierr = MPI_Bcast(&msg, 1, MPI_INT, 0, my_iosys->io_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + LOG((1, "pio_msg_handler msg MPI_Bcast complete msg = %d", msg)); + + /* Handle the message. This code is run on all IO tasks. */ + switch (msg) + { + case PIO_MSG_INQ_TYPE: + inq_type_handler(my_iosys); + break; + case PIO_MSG_INQ_FORMAT: + inq_format_handler(my_iosys); + break; + case PIO_MSG_CREATE_FILE: + create_file_handler(my_iosys); + break; + case PIO_MSG_SYNC: + sync_file_handler(my_iosys); + break; + case PIO_MSG_ENDDEF: + case PIO_MSG_REDEF: + change_def_file_handler(my_iosys, msg); + break; + case PIO_MSG_OPEN_FILE: + open_file_handler(my_iosys); + break; + case PIO_MSG_CLOSE_FILE: + close_file_handler(my_iosys); + break; + case PIO_MSG_DELETE_FILE: + delete_file_handler(my_iosys); + break; + case PIO_MSG_RENAME_DIM: + rename_dim_handler(my_iosys); + break; + case PIO_MSG_RENAME_VAR: + rename_var_handler(my_iosys); + break; + case PIO_MSG_RENAME_ATT: + rename_att_handler(my_iosys); + break; + case PIO_MSG_DEL_ATT: + delete_att_handler(my_iosys); + break; + case PIO_MSG_DEF_DIM: + def_dim_handler(my_iosys); + break; + case PIO_MSG_DEF_VAR: + def_var_handler(my_iosys); + break; + case PIO_MSG_INQ: + inq_handler(my_iosys); + break; + case PIO_MSG_INQ_DIM: + inq_dim_handler(my_iosys, msg); + break; + case PIO_MSG_INQ_DIMID: + inq_dimid_handler(my_iosys); + break; + case PIO_MSG_INQ_VAR: + inq_var_handler(my_iosys); + break; + case PIO_MSG_GET_ATT: + ret = att_get_handler(my_iosys); + break; + case PIO_MSG_PUT_ATT: + ret = att_put_handler(my_iosys); + break; + case PIO_MSG_INQ_VARID: + inq_varid_handler(my_iosys); + break; + case PIO_MSG_INQ_ATT: + inq_att_handler(my_iosys); + break; + case PIO_MSG_INQ_ATTNAME: + inq_attname_handler(my_iosys); + break; + case PIO_MSG_INQ_ATTID: + inq_attid_handler(my_iosys); + break; + case PIO_MSG_GET_VARS: + get_vars_handler(my_iosys); + break; + case PIO_MSG_PUT_VARS: + put_vars_handler(my_iosys); + break; + case PIO_MSG_INITDECOMP_DOF: + initdecomp_dof_handler(my_iosys); + break; + case PIO_MSG_WRITEDARRAY: + writedarray_handler(my_iosys); + break; + case PIO_MSG_READDARRAY: + readdarray_handler(my_iosys); + break; + case PIO_MSG_SETERRORHANDLING: + seterrorhandling_handler(my_iosys); + break; + case PIO_MSG_FREEDECOMP: + freedecomp_handler(my_iosys); + break; + case PIO_MSG_EXIT: + finalize_handler(my_iosys); + msg = -1; + break; + default: + pio_callback_handler(my_iosys, msg); + } + + /* If an error was returned by the handler, do something! */ + if (ret) + { + LOG((0, "hander returned error code %d", ret)); + MPI_Finalize(); + } + + /* Unless finalize was called, listen for another msg from the + * component whose message we just handled. */ + if (!io_rank && msg != -1) + { + my_iosys = &iosys[index]; + mpierr = MPI_Irecv(&msg, 1, MPI_INT, my_iosys->comproot, MPI_ANY_TAG, my_iosys->union_comm, + &req[index]); + LOG((3, "pio_msg_handler called MPI_Irecv req[%d] = %d\n", index, req[index])); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + } + + } + + return PIO_NOERR; +} + +int +pio_iosys_print(int my_rank, iosystem_desc_t *iosys) +{ + printf("%d iosysid: %d\n", my_rank, iosys->iosysid); + if (iosys->union_comm == MPI_COMM_NULL) + printf("%d union_comm: MPI_COMM_NULL ", my_rank); + else + printf("%d union_comm: %d ", my_rank, iosys->union_comm); + + if (iosys->comp_comm == MPI_COMM_NULL) + printf("comp_comm: MPI_COMM_NULL "); + else + printf("comp_comm: %d ", iosys->comp_comm); + + if (iosys->io_comm == MPI_COMM_NULL) + printf("io_comm: MPI_COMM_NULL "); + else + printf("io_comm: %d ", iosys->io_comm); + + if (iosys->intercomm == MPI_COMM_NULL) + printf("intercomm: MPI_COMM_NULL\n"); + else + printf("intercomm: %d\n", iosys->intercomm); + + printf("%d num_iotasks=%d num_comptasks=%d union_rank=%d, comp_rank=%d, " + "io_rank=%d async_interface=%d\n", + my_rank, iosys->num_iotasks, iosys->num_comptasks, iosys->union_rank, + iosys->comp_rank, iosys->io_rank, iosys->async_interface); + + printf("%d ioroot=%d comproot=%d iomaster=%d, compmaster=%d\n", + my_rank, iosys->ioroot, iosys->comproot, iosys->iomaster, + iosys->compmaster); + + printf("%d iotasks:", my_rank); + for (int i = 0; i < iosys->num_iotasks; i++) + printf("%d ", iosys->ioranks[i]); + printf("\n"); + return PIO_NOERR; +} + +/** @ingroup PIO_init + * Library initialization used when IO tasks are distinct from compute + * tasks. + * + * This is a collective call. Input parameters are read on + * comp_rank=0 values on other tasks are ignored. This variation of + * PIO_init sets up a distinct set of tasks to handle IO, these tasks + * do not return from this call. Instead they go to an internal loop + * and wait to receive further instructions from the computational + * tasks. + * + * For 4 tasks, to have 2 of them be computational, and 2 of them + * be IO, I would provide the following: + * + * component_count = 1 + * + * peer_comm = MPI_COMM_WORLD + * + * comp_comms = an array with one element, an MPI (intra) communicator + * that contains the two tasks designated to do computation + * (processors 0, 1). + + * io_comm = an MPI (intra) communicator with the other two tasks (2, + * 3). + * + * iosysidp = pointer that gets the IO system ID. + * + * Fortran function (from PIO1, in piolib_mod.F90) is: + * + * subroutine init_intercom(component_count, peer_comm, comp_comms, + * io_comm, iosystem, rearr_opts) + * + * Some notes from Jim: + * + * Components and Component Count + * ------------------------------ + * + * It's a cesm thing - the cesm model is composed of several component + * models (atm, ocn, ice, lnd, etc) that may or may not be collocated + * on mpi tasks. Since for intercomm the IOCOMM tasks are a subset of + * the compute tasks for a given component we have a separate iocomm + * for each model component. and we call init_inracomm independently + * for each component. + * + * When the IO tasks are independent of any model component then we + * can have all of the components share one set of iotasks and we call + * init_intercomm once with the information for all components. + * + * Inter vs Intra Communicators + * ---------------------------- + * + * ​For an intra you just need to provide the compute comm, pio creates + * an io comm as a subset of that compute comm. + * + * For an inter you need to provide multiple comms - peer comm is the + * communicator that is going to encompass all of the tasks - usually + * this will be mpi_comm_world. Then you need to provide a comm for + * each component model that will share the io server, then an + * io_comm. + * + * Example of Communicators + * ------------------------ + * + * Starting from MPI_COMM_WORLD the calling program will create an + * IO_COMM and one or more COMP_COMMs, I think an example might be best: + * + * Suppose we have 10 tasks and 2 of them will be IO tasks. Then 0:7 + * are in COMP_COMM and 8:9 are in IO_COMM In this case on tasks 0:7 + * COMP_COMM is defined and IO_COMM is MPI_COMM_NULL and on tasks 8:9 + * IO_COMM is defined and COMP_COMM is MPI_COMM_NULL The communicators + * to handle communications between COMP_COMM and IO_COMM are defined + * in init_intercomm and held in a pio internal data structure. + * + * Return or Not + * ------------- + * + * The io_comm tasks do not return from the init_intercomm routine. + * + * Sequence of Events to do Asynch I/O + * ----------------------------------- + * + * Here is the sequence of events that needs to occur when an IO + * operation is called from the collection of compute tasks. I'm + * going to use pio_put_var because write_darray has some special + * characteristics that make it a bit more complicated... + * + * Compute tasks call pio_put_var with an integer argument + * + * The MPI_Send sends a message from comp_rank=0 to io_rank=0 on + * union_comm (a comm defined as the union of io and compute tasks) + * msg is an integer which indicates the function being called, in + * this case the msg is PIO_MSG_PUT_VAR_INT + * + * The iotasks now know what additional arguments they should expect + * to receive from the compute tasks, in this case a file handle, a + * variable id, the length of the array and the array itself. + * + * The iotasks now have the information they need to complete the + * operation and they call the pio_put_var routine. (In pio1 this bit + * of code is in pio_get_put_callbacks.F90.in) + * + * After the netcdf operation is completed (in the case of an inq or + * get operation) the result is communicated back to the compute + * tasks. + * + * + * @param component_count The number of computational (ex. model) + * components to associate with this IO component + * + * @param peer_comm The communicator from which all other communicator + * arguments are derived + * + * @param comp_comms An array containing the computational + * communicator for each of the computational components. The I/O + * tasks pass MPI_COMM_NULL for this parameter. + * +`* @param io_comm The io communicator. Processing tasks pass + * MPI_COMM_NULL for this parameter. + * + * @param iosysidp An array of length component_count. It will get the + * iosysid for each component. + * + * @return PIO_NOERR on success, error code otherwise. + */ +int PIOc_Init_Intercomm(int component_count, MPI_Comm peer_comm, + MPI_Comm *comp_comms, MPI_Comm io_comm, int *iosysidp) +{ + iosystem_desc_t *iosys; + iosystem_desc_t *my_iosys; + int ierr = PIO_NOERR; + int mpierr; + int my_rank; + int iam; + int io_leader, comp_leader; + int root; + + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + + /* Allocate struct to hold io system info for each component. */ + if (!(iosys = (iosystem_desc_t *) calloc(1, sizeof(iosystem_desc_t) * component_count))) + ierr = PIO_ENOMEM; + + if (!ierr) + for (int cmp = 0; cmp < component_count; cmp++) + { + /* These are used when using the intercomm. */ + int comp_master = MPI_PROC_NULL, io_master = MPI_PROC_NULL; + + /* Get a pointer to the iosys struct */ + my_iosys = &iosys[cmp]; + + /* Create an MPI info object. */ + CheckMPIReturn(MPI_Info_create(&(my_iosys->info)),__FILE__,__LINE__); + + /* This task is part of the computation communicator. */ + if (comp_comms[cmp] != MPI_COMM_NULL) + { + /* Copy the computation communicator. */ + mpierr = MPI_Comm_dup(comp_comms[cmp], &my_iosys->comp_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Create an MPI group with the computation tasks. */ + mpierr = MPI_Comm_group(my_iosys->comp_comm, &my_iosys->compgroup); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Find out how many tasks are in this communicator. */ + mpierr = MPI_Comm_size(iosys->comp_comm, &my_iosys->num_comptasks); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Set the rank within the comp_comm. */ + mpierr = MPI_Comm_rank(my_iosys->comp_comm, &my_iosys->comp_rank); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Find the rank of the io leader in peer_comm. */ + iam = -1; + mpierr = MPI_Allreduce(&iam, &io_leader, 1, MPI_INT, MPI_MAX, peer_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Find the rank of the comp leader in peer_comm. */ + if (!my_iosys->comp_rank) + { + mpierr = MPI_Comm_rank(peer_comm, &iam); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + } + else + iam = -1; + + /* Find the lucky comp_leader task. */ + mpierr = MPI_Allreduce(&iam, &comp_leader, 1, MPI_INT, MPI_MAX, peer_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Is this the compmaster? Only if the comp_rank is zero. */ + if (!my_iosys->comp_rank) + { + my_iosys->compmaster = MPI_ROOT; + comp_master = MPI_ROOT; + } + else + my_iosys->compmaster = MPI_PROC_NULL; + + /* Set up the intercomm from the computation side. */ + mpierr = MPI_Intercomm_create(my_iosys->comp_comm, 0, peer_comm, + io_leader, cmp, &my_iosys->intercomm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Create the union communicator. */ + mpierr = MPI_Intercomm_merge(my_iosys->intercomm, 0, &my_iosys->union_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + } + else + { + my_iosys->comp_comm = MPI_COMM_NULL; + my_iosys->compgroup = MPI_GROUP_NULL; + my_iosys->comp_rank = -1; + } + + /* This task is part of the IO communicator, so set up the + * IO stuff. */ + if (io_comm != MPI_COMM_NULL) + { + /* Copy the IO communicator. */ + mpierr = MPI_Comm_dup(io_comm, &my_iosys->io_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Get an MPI group that includes the io tasks. */ + mpierr = MPI_Comm_group(my_iosys->io_comm, &my_iosys->iogroup); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Find out how many tasks are in this communicator. */ + mpierr = MPI_Comm_size(iosys->io_comm, &my_iosys->num_iotasks); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Set the rank within the io_comm. */ + mpierr = MPI_Comm_rank(my_iosys->io_comm, &my_iosys->io_rank); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Find the rank of the io leader in peer_comm. */ + if (!my_iosys->io_rank) + { + mpierr = MPI_Comm_rank(peer_comm, &iam); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + } + else + iam = -1; + + /* Find the lucky io_leader task. */ + mpierr = MPI_Allreduce(&iam, &io_leader, 1, MPI_INT, MPI_MAX, peer_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Find the rank of the comp leader in peer_comm. */ + iam = -1; + mpierr = MPI_Allreduce(&iam, &comp_leader, 1, MPI_INT, MPI_MAX, peer_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* This is an io task. */ + my_iosys->ioproc = true; + + /* Is this the iomaster? Only if the io_rank is zero. */ + if (!my_iosys->io_rank) + { + my_iosys->iomaster = MPI_ROOT; + io_master = MPI_ROOT; + } + else + my_iosys->iomaster = 0; + + /* Set up the intercomm from the I/O side. */ + mpierr = MPI_Intercomm_create(my_iosys->io_comm, 0, peer_comm, + comp_leader, cmp, &my_iosys->intercomm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Create the union communicator. */ + mpierr = MPI_Intercomm_merge(my_iosys->intercomm, 0, &my_iosys->union_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + } + else + { + my_iosys->io_comm = MPI_COMM_NULL; + my_iosys->iogroup = MPI_GROUP_NULL; + my_iosys->io_rank = -1; + my_iosys->ioproc = false; + my_iosys->iomaster = false; + } + + /* my_comm points to the union communicator for async, and + * the comp_comm for non-async. It should not be freed + * since it is not a proper copy of the commuicator, just + * a copy of the reference to it. */ + my_iosys->my_comm = my_iosys->union_comm; + + /* Find rank in union communicator. */ + mpierr = MPI_Comm_rank(my_iosys->union_comm, &my_iosys->union_rank); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + + /* Find the rank of the io leader in the union communicator. */ + if (!my_iosys->io_rank) + my_iosys->ioroot = my_iosys->union_rank; + else + my_iosys->ioroot = -1; + + /* Distribute the answer to all tasks. */ + mpierr = MPI_Allreduce(&my_iosys->ioroot, &root, 1, MPI_INT, MPI_MAX, + my_iosys->union_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + my_iosys->ioroot = root; + + /* Find the rank of the computation leader in the union + * communicator. */ + if (!my_iosys->comp_rank) + my_iosys->comproot = my_iosys->union_rank; + else + my_iosys->comproot = -1; + + /* Distribute the answer to all tasks. */ + mpierr = MPI_Allreduce(&my_iosys->comproot, &root, 1, MPI_INT, MPI_MAX, + my_iosys->union_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + my_iosys->comproot = root; + + /* Send the number of tasks in the IO and computation + communicators to each other over the intercomm. This is + a one-to-all bcast from the local task that passes + MPI_ROOT as the root (all other local tasks should pass + MPI_PROC_NULL as the root). The bcast is recieved by + all the members of the leaf group which each pass the + rank of the root relative to the root group. */ + if (io_comm != MPI_COMM_NULL) + { + comp_master = 0; + mpierr = MPI_Bcast(&my_iosys->num_comptasks, 1, MPI_INT, comp_master, + my_iosys->intercomm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + mpierr = MPI_Bcast(&my_iosys->num_iotasks, 1, MPI_INT, io_master, + my_iosys->intercomm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + } + else + { + io_master = 0; + mpierr = MPI_Bcast(&my_iosys->num_comptasks, 1, MPI_INT, comp_master, + my_iosys->intercomm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + mpierr = MPI_Bcast(&my_iosys->num_iotasks, 1, MPI_INT, io_master, + my_iosys->intercomm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + } + + /* Allocate an array to hold the ranks of the IO tasks + * within the union communicator. */ + if (!(my_iosys->ioranks = malloc(my_iosys->num_iotasks * sizeof(int)))) + return PIO_ENOMEM; + + /* Allocate a temp array to help get the IO ranks. */ + int *tmp_ioranks; + if (!(tmp_ioranks = malloc(my_iosys->num_iotasks * sizeof(int)))) + return PIO_ENOMEM; + + /* Init array, then have IO tasks set their values, then + * use allreduce to distribute results to all tasks. */ + for (int cnt = 0 ; cnt < my_iosys->num_iotasks; cnt++) + tmp_ioranks[cnt] = -1; + if (io_comm != MPI_COMM_NULL) + tmp_ioranks[my_iosys->io_rank] = my_iosys->union_rank; + mpierr = MPI_Allreduce(tmp_ioranks, my_iosys->ioranks, my_iosys->num_iotasks, MPI_INT, MPI_MAX, + my_iosys->union_comm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + + /* Free temp array. */ + free(tmp_ioranks); + + /* Set the default error handling. */ + my_iosys->error_handler = PIO_INTERNAL_ERROR; + + /* We do support asynch interface. */ + my_iosys->async_interface = true; + + /* For debug purposes, print the contents of the struct. */ + /* for (int t = 0; t < my_iosys->num_iotasks + my_iosys->num_comptasks; t++) */ + /* { */ + /* MPI_Barrier(my_iosys->union_comm); */ + /* if (my_rank == t) */ + /* pio_iosys_print(my_rank, my_iosys); */ + /* } */ + + /* Add this id to the list of PIO iosystem ids. */ + iosysidp[cmp] = pio_add_to_iosystem_list(my_iosys); + LOG((2, "added to iosystem_list iosysid = %d", iosysidp[cmp])); + + /* Now call the function from which the IO tasks will not + * return until the PIO_MSG_EXIT message is sent. */ + if (io_comm != MPI_COMM_NULL) + if ((ierr = pio_msg_handler(my_iosys->io_rank, component_count, iosys))) + return ierr; + } + + /* If there was an error, make sure all tasks see it. */ + if (ierr) + { + /*mpierr = MPI_Bcast(&ierr, 1, MPI_INT, iosys->my_rank, iosys->intercomm);*/ + mpierr = MPI_Bcast(&ierr, 1, MPI_INT, 0, iosys->intercomm); + CheckMPIReturn(mpierr, __FILE__, __LINE__); + if (mpierr) + ierr = PIO_EIO; + } + + return ierr; +} diff --git a/src/clib/pio_nc.c b/src/clib/pio_nc.c index f511475a4f6c..52a376f0c266 100644 --- a/src/clib/pio_nc.c +++ b/src/clib/pio_nc.c @@ -122,7 +122,7 @@ int PIOc_inq_dimname (int ncid, int dimid, char *name) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_DIMNAME; + msg = PIO_MSG_INQ_DIM; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -961,7 +961,7 @@ int PIOc_inq_vartype (int ncid, int varid, nc_type *xtypep) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_VARTYPE; + msg = PIO_MSG_INQ_VAR; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -1108,7 +1108,7 @@ int PIOc_inq_vardimid (int ncid, int varid, int *dimidsp) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_VARDIMID; + msg = PIO_MSG_INQ_VAR; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -1340,7 +1340,7 @@ int PIOc_inq_attlen (int ncid, int varid, const char *name, PIO_Offset *lenp) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_ATTLEN; + msg = PIO_MSG_INQ_ATT; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -1415,7 +1415,7 @@ int PIOc_inq_atttype (int ncid, int varid, const char *name, nc_type *xtypep) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_ATTTYPE; + msg = PIO_MSG_INQ_ATT; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -1561,7 +1561,7 @@ int PIOc_inq_natts (int ncid, int *ngattsp) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_NATTS; + msg = PIO_MSG_INQ; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -2322,7 +2322,7 @@ int PIOc_inq_attname (int ncid, int varid, int attnum, char *name) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_ATTNAME; + msg = PIO_MSG_INQ_ATT; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -2551,7 +2551,7 @@ int PIOc_inq_unlimdim (int ncid, int *unlimdimidp) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_UNLIMDIM; + msg = PIO_MSG_INQ; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -2702,7 +2702,7 @@ int PIOc_inq_ndims (int ncid, int *ndimsp) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_NDIMS; + msg = PIO_MSG_INQ; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -2848,7 +2848,7 @@ int PIOc_inq_nvars (int ncid, int *nvarsp) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_NVARS; + msg = PIO_MSG_INQ; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -3141,7 +3141,7 @@ int PIOc_inq_varnatts (int ncid, int varid, int *nattsp) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_VARNATTS; + msg = PIO_MSG_INQ_VAR; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -3444,7 +3444,7 @@ int PIOc_inq_dimlen (int ncid, int dimid, PIO_Offset *lenp) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_DIMLEN; + msg = PIO_MSG_INQ_DIM; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) @@ -3674,7 +3674,7 @@ int PIOc_inq_varndims (int ncid, int varid, int *ndimsp) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_VARNDIMS; + msg = PIO_MSG_INQ_VAR; if(file->varlist[varid].ndims > 0){ (*ndimsp) = file->varlist[varid].ndims; return PIO_NOERR; @@ -3753,7 +3753,7 @@ int PIOc_inq_varname (int ncid, int varid, char *name) if(file == NULL) return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_VARNAME; + msg = PIO_MSG_INQ_VAR; if(ios->async_interface && ! ios->ioproc){ if(ios->compmaster) diff --git a/src/clib/pio_nc_async.c b/src/clib/pio_nc_async.c index 9e9f04a45db7..b05a2637ffda 100644 --- a/src/clib/pio_nc_async.c +++ b/src/clib/pio_nc_async.c @@ -15,139 +15,368 @@ * @date Feburary 2014, April 2016 */ +#include #include #include -/** Internal function to call nc_inq. Call this function only in I/O - * tasks. */ -int -pio_io_inq(int ncid, int *ndimsp, int *nvarsp, int *ngattsp, - int *unlimdimidp) +/** + * @ingroup PIOc_inq + * The PIO-C interface for the NetCDF function nc_inq. + * + * This routine is called collectively by all tasks in the + * communicator ios.union_comm. For more information on the underlying + * NetCDF commmand please read about this function in the NetCDF + * documentation at: + * http://www.unidata.ucar.edu/software/netcdf/docs/group__datasets.html + * + * @param ncid the ncid of the open file, obtained from + * PIOc_openfile() or PIOc_createfile(). + * + * @return PIO_NOERR for success, error code otherwise. See + * PIOc_Set_File_Error_Handling + */ +int PIOc_inq(int ncid, int *ndimsp, int *nvarsp, int *ngattsp, + int *unlimdimidp) { - file_desc_t *file; - char *errstr = NULL; - int ierr = PIO_NOERR; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - int my_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - printf("%d pio_io_inq ncid = %d\n", my_rank, ncid); + LOG((1, "PIOc_inq ncid = %d", ncid)); + /* Find the info about this file. */ if (!(file = pio_get_file_from_id(ncid))) - return PIO_EBADID; + return PIO_EBADID; + ios = file->iosystem; + + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ; /** Message for async notification. */ + char ndims_present = ndimsp ? true : false; + char nvars_present = nvarsp ? true : false; + char ngatts_present = ngattsp ? true : false; + char unlimdimid_present = unlimdimidp ? true : false; + + if (ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&ndims_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&nvars_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&ngatts_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&unlimdimid_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } - switch (file->iotype) + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) { +#ifdef _PNETCDF + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_inq(ncid, ndimsp, nvarsp, ngattsp, unlimdimidp); +#endif /* _PNETCDF */ #ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq(ncid, ndimsp, nvarsp, ngattsp, unlimdimidp); - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - printf("%d pio_io_inq file->iosystem->io_rank = %d\n", my_rank, file->iosystem->io_rank); - if (!file->iosystem->io_rank) - { - /* Should not be necessary to do this - nc_inq should - * handle null pointers. This has been reported as a bug - * to netCDF developers. */ - int tmp_ndims, tmp_var, tmp_gatts, tmp_unl; - if (!ndimsp) - ndimsp = &tmp_ndims; - if (!nvarsp) - nvarsp = &tmp_var; - if (!ngattsp) - ngattsp = &tmp_gatts; - if (!unlimdimidp) - unlimdimidp = &tmp_unl; - ierr = nc_inq(ncid, ndimsp, nvarsp, ngattsp, unlimdimidp); - } - break; -#endif + if (file->iotype == PIO_IOTYPE_NETCDF && file->do_io) + { + /* Should not be necessary to do this - nc_inq should + * handle null pointers. This has been reported as a bug + * to netCDF developers. */ + int tmp_ndims, tmp_nvars, tmp_ngatts, tmp_unlimdimid; + ierr = nc_inq(ncid, &tmp_ndims, &tmp_nvars, &tmp_ngatts, &tmp_unlimdimid); + if (ndimsp) + *ndimsp = tmp_ndims; + if (nvarsp) + *nvarsp = tmp_nvars; + if (ngattsp) + *ngattsp = tmp_ngatts; + if (unlimdimidp) + *unlimdimidp = tmp_unlimdimid; + } else if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq(ncid, ndimsp, nvarsp, ngattsp, unlimdimidp); +#endif /* _NETCDF */ + LOG((2, "PIOc_inq netcdf call returned %d", ierr)); + } + + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. Ignore NULL parameters. */ + if (!ierr) + { + if (ndimsp) + if ((mpierr = MPI_Bcast(ndimsp, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + + if (nvarsp) + if ((mpierr = MPI_Bcast(nvarsp, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + + if (ngattsp) + if ((mpierr = MPI_Bcast(ngattsp, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + + if (unlimdimidp) + if ((mpierr = MPI_Bcast(unlimdimidp, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + } + + return ierr; +} + +/** + * @ingroup PIOc_inq_ndims + * The PIO-C interface for the NetCDF function nc_inq_ndims. + */ +int PIOc_inq_ndims (int ncid, int *ndimsp) +{ + LOG((1, "PIOc_inq_ndims")); + return PIOc_inq(ncid, ndimsp, NULL, NULL, NULL); +} + +/** + * @ingroup PIOc_inq_nvars + * The PIO-C interface for the NetCDF function nc_inq_nvars. + */ +int PIOc_inq_nvars(int ncid, int *nvarsp) +{ + return PIOc_inq(ncid, NULL, nvarsp, NULL, NULL); +} + +/** + * @ingroup PIOc_inq_natts + * The PIO-C interface for the NetCDF function nc_inq_natts. + */ +int PIOc_inq_natts(int ncid, int *ngattsp) +{ + return PIOc_inq(ncid, NULL, NULL, ngattsp, NULL); +} + +/** + * @ingroup PIOc_inq_unlimdim + * The PIO-C interface for the NetCDF function nc_inq_unlimdim. + */ +int PIOc_inq_unlimdim(int ncid, int *unlimdimidp) +{ + return PIOc_inq(ncid, NULL, NULL, unlimdimidp, NULL); +} + +/** Internal function to provide inq_type function for pnetcdf. */ +int pioc_pnetcdf_inq_type(int ncid, nc_type xtype, char *name, + PIO_Offset *sizep) +{ + int typelen; + char typename[NC_MAX_NAME + 1]; + + switch (xtype) + { + case NC_UBYTE: + case NC_BYTE: + case NC_CHAR: + typelen = 1; + break; + case NC_SHORT: + case NC_USHORT: + typelen = 2; + break; + case NC_UINT: + case NC_INT: + case NC_FLOAT: + typelen = 4; + break; + case NC_UINT64: + case NC_INT64: + case NC_DOUBLE: + typelen = 8; + break; + } + + /* If pointers were supplied, copy results. */ + if (sizep) + *sizep = typelen; + if (name) + strcpy(name, "some type"); + + return PIO_NOERR; +} + +/** + * @ingroup PIOc_typelen + * The PIO-C interface for the NetCDF function nctypelen. + */ +int PIOc_inq_type(int ncid, nc_type xtype, char *name, PIO_Offset *sizep) +{ + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ + int typelen; + + LOG((1, "PIOc_inq_type ncid = %d xtype = %d", ncid, xtype)); + + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; + ios = file->iosystem; + + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ_TYPE; /** Message for async notification. */ + char name_present = name ? true : false; + char size_present = sizep ? true : false; + + if (ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&xtype, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&size_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq(ncid, ndimsp, nvarsp, ngattsp, unlimdimidp); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = pioc_pnetcdf_inq_type(ncid, xtype, name, sizep); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq_type(ncid, xtype, name, (size_t *)sizep); +#endif /* _NETCDF */ + LOG((2, "PIOc_inq_type netcdf call returned %d", ierr)); } - if(ierr != PIO_NOERR) + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. Ignore NULL parameters. */ + if (!ierr) { - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + if (name) + { + int slen; + if (ios->iomaster) + slen = strlen(name); + if ((mpierr = MPI_Bcast(&slen, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + if (!mpierr) + if ((mpierr = MPI_Bcast((void *)name, slen + 1, MPI_CHAR, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + } + if (sizep) + if ((mpierr = MPI_Bcast(sizep , 1, MPI_OFFSET, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); } return ierr; } /** - * @ingroup PIOc_inq - * The PIO-C interface for the NetCDF function nc_inq. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__datasets.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @return PIO_NOERR for success, error code otherwise. See - * PIOc_Set_File_Error_Handling + * @ingroup PIOc_inq_format + * The PIO-C interface for the NetCDF function nc_inq_format. */ -int PIOc_inq (int ncid, int *ndimsp, int *nvarsp, int *ngattsp, - int *unlimdimidp) +int PIOc_inq_format (int ncid, int *formatp) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - int my_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - printf("%d PIOc_inq ncid = %d\n", my_rank, ncid); - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ + + LOG((1, "PIOc_inq ncid = %d", ncid)); + + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ_FORMAT; + char format_present = formatp ? true : false; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&format_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { +#ifdef _PNETCDF + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_inq_format(file->fh, formatp); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq_format(file->fh, formatp); +#endif /* _NETCDF */ + LOG((2, "PIOc_inq netcdf call returned %d", ierr)); } - if(ios->ioproc){ - ierr = pio_io_inq(file->fh, ndimsp, nvarsp, ngattsp, unlimdimidp); - printf("%d PIOc_inq pio_io_inq returned %d\n", my_rank, ierr); - ierr = check_netcdf(file, ierr, errstr,__LINE__); - } - if(ndimsp != NULL) + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. Ignore NULL parameters. */ + if (!ierr) { - printf("%d PIOc_inq Bcast ios->ioroot = %d *ndimsp = %d\n", my_rank, ios->ioroot, *ndimsp); - mpierr = MPI_Bcast(ndimsp, 1, MPI_INT, ios->ioroot, ios->my_comm); + if (formatp) + if ((mpierr = MPI_Bcast(formatp , 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); } - if(nvarsp != NULL) - mpierr = MPI_Bcast(nvarsp, 1, MPI_INT, ios->ioroot, ios->my_comm); - if(ngattsp != NULL) - mpierr = MPI_Bcast(ngattsp, 1, MPI_INT, ios->ioroot, ios->my_comm); - if(unlimdimidp != NULL) - mpierr = MPI_Bcast(unlimdimidp, 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); + return ierr; } /** - * @ingroup PIOc_inq_dimname - * The PIO-C interface for the NetCDF function nc_inq_dimname. + * @ingroup PIOc_inq_dim + * The PIO-C interface for the NetCDF function nc_inq_dim. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand @@ -156,470 +385,592 @@ int PIOc_inq (int ncid, int *ndimsp, int *nvarsp, int *ngattsp, * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). + * @param lenp a pointer that will get the number of values * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_inq_dimname (int ncid, int dimid, char *name) +int PIOc_inq_dim(int ncid, int dimid, char *name, PIO_Offset *lenp) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - errstr = NULL; - ierr = PIO_NOERR; + LOG((1, "PIOc_inq_dim")); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Get the file info, based on the ncid. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_DIMNAME; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&dimid, 1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_dimname(file->fh, dimid, name);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_dimname(file->fh, dimid, name);; - } - break; -#endif + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ_DIM; + char name_present = name ? true : false; + char len_present = lenp ? true : false; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&dimid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + LOG((2, "PIOc_inq netcdf Bcast name_present = %d", name_present)); + if (!mpierr) + mpierr = MPI_Bcast(&len_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + LOG((2, "PIOc_inq netcdf Bcast len_present = %d", len_present)); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_dimname(file->fh, dimid, name);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_inq_dim(file->fh, dimid, name, lenp);; +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq_dim(file->fh, dimid, name, (size_t *)lenp);; +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (name) + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. Ignore NULL parameters. */ + if (!ierr) { - int slen; - if(ios->iomaster) - slen = (int) strlen(name) + 1; - mpierr = MPI_Bcast(&slen, 1, MPI_INT, ios->ioroot, ios->my_comm); - mpierr = MPI_Bcast((void *)name, slen, MPI_CHAR, ios->ioroot, ios->my_comm); + if (name) + { + int slen; + if (ios->iomaster) + slen = strlen(name); + if ((mpierr = MPI_Bcast(&slen, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + if ((mpierr = MPI_Bcast((void *)name, slen + 1, MPI_CHAR, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + } + + if (lenp) + if ((mpierr = MPI_Bcast(lenp , 1, MPI_OFFSET, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); } - if(errstr != NULL) free(errstr); + return ierr; } /** - * @ingroup PIOc_put_att_short - * The PIO-C interface for the NetCDF function nc_put_att_short. + * @ingroup PIOc_inq_dimname + * The PIO-C interface for the NetCDF function nc_inq_dimname. + */ +int PIOc_inq_dimname(int ncid, int dimid, char *name) +{ + return PIOc_inq_dim(ncid, dimid, name, NULL); +} + +/** + * @ingroup PIOc_inq_dimlen + * The PIO-C interface for the NetCDF function nc_inq_dimlen. + */ +int PIOc_inq_dimlen(int ncid, int dimid, PIO_Offset *lenp) +{ + return PIOc_inq_dim(ncid, dimid, NULL, lenp); +} + +/** + * @ingroup PIOc_inq_dimid + * The PIO-C interface for the NetCDF function nc_inq_dimid. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. + * @param idp a pointer that will get the id of the variable or attribute. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_put_att_short (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const short *op) +int PIOc_inq_dimid(int ncid, const char *name, int *idp) { - int ierr; - int msg; - int mpierr; iosystem_desc_t *ios; file_desc_t *file; - char *errstr; + int ierr = PIO_NOERR; + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - errstr = NULL; - ierr = PIO_NOERR; + /* Name must be provided. */ + if (!name) + return PIO_EINVAL; + + LOG((1, "PIOc_inq_dimid name = %s", name)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Get the file info, based on the ncid. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_SHORT; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + /* If using async, and not an IO task, then send parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ_DIMID; + char id_present = idp ? true : false; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + int namelen = strlen(name); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&id_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* IO tasks call the netCDF functions. */ + if (ios->ioproc) + { +#ifdef _PNETCDF + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_inq_dimid(file->fh, name, idp);; +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq_dimid(file->fh, name, idp);; +#endif /* _NETCDF */ } + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + check_netcdf(file, ierr, __FILE__, __LINE__); - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_short(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_short(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_short(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } + /* Broadcast results. */ + if (!ierr) + if (idp) + if ((mpierr = MPI_Bcast(idp, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); return ierr; } /** - * @ingroup PIOc_rename_dim - * The PIO-C interface for the NetCDF function nc_rename_dim. + * @ingroup PIOc_inq_var + * The PIO-C interface for the NetCDF function nc_inq_var. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). + * @param varid the variable ID. + * @param xtypep a pointer that will get the type of the attribute. + * @param nattsp a pointer that will get the number of attributes * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_rename_dim (int ncid, int dimid, const char *name) +int PIOc_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, + int *dimidsp, int *nattsp) { - int ierr; - int msg; - int mpierr; iosystem_desc_t *ios; file_desc_t *file; - char *errstr; + int ndims; /** The number of dimensions for this variable. */ + int ierr = PIO_NOERR; + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - errstr = NULL; - ierr = PIO_NOERR; + LOG((1, "PIOc_inq_var ncid = %d varid = %d", ncid, varid)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Get the file info, based on the ncid. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_RENAME_DIM; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_rename_dim(file->fh, dimid, name);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_rename_dim(file->fh, dimid, name);; - } - break; -#endif + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ_VAR; + char name_present = name ? true : false; + char xtype_present = xtypep ? true : false; + char ndims_present = ndimsp ? true : false; + char dimids_present = dimidsp ? true : false; + char natts_present = nattsp ? true : false; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&xtype_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&ndims_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&dimids_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&natts_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + LOG((2, "PIOc_inq_var name_present = %d xtype_present = %d ndims_present = %d " + "dimids_present = %d, natts_present = %d nattsp = %d", + name_present, xtype_present, ndims_present, dimids_present, natts_present, nattsp)); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* Call the netCDF layer. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_rename_dim(file->fh, dimid, name);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + { + ierr = ncmpi_inq_varndims(file->fh, varid, &ndims); + if (!ierr) + ierr = ncmpi_inq_var(file->fh, varid, name, xtypep, ndimsp, dimidsp, nattsp);; + } +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + { + ierr = nc_inq_varndims(file->fh, varid, &ndims); + if (!ierr) + ierr = nc_inq_var(file->fh, varid, name, xtypep, ndimsp, dimidsp, nattsp); + } +#endif /* _NETCDF */ + } + + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast the results for non-null pointers. */ + if (!ierr) + { + if (name) + { + int slen; + if(ios->iomaster) + slen = strlen(name); + if ((mpierr = MPI_Bcast(&slen, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + if ((mpierr = MPI_Bcast((void *)name, slen + 1, MPI_CHAR, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + } + if (xtypep) + if ((mpierr = MPI_Bcast(xtypep, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + + if (ndimsp) + { + if ((mpierr = MPI_Bcast(ndimsp, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + file->varlist[varid].ndims = (*ndimsp); + } + if (dimidsp) + { + if ((mpierr = MPI_Bcast(&ndims, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + if ((mpierr = MPI_Bcast(dimidsp, ndims, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + } + if (nattsp) + if ((mpierr = MPI_Bcast(nattsp, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); return ierr; } /** - * @ingroup PIOc_get_att_double - * The PIO-C interface for the NetCDF function nc_get_att_double. + * @ingroup PIOc_inq_varname + * The PIO-C interface for the NetCDF function nc_inq_varname. + */ +int PIOc_inq_varname (int ncid, int varid, char *name) +{ + return PIOc_inq_var(ncid, varid, name, NULL, NULL, NULL, NULL); +} + +/** + * @ingroup PIOc_inq_vartype + * The PIO-C interface for the NetCDF function nc_inq_vartype. + */ +int PIOc_inq_vartype (int ncid, int varid, nc_type *xtypep) +{ + return PIOc_inq_var(ncid, varid, NULL, xtypep, NULL, NULL, NULL); +} + +/** + * @ingroup PIOc_inq_varndims + * The PIO-C interface for the NetCDF function nc_inq_varndims. + */ +int PIOc_inq_varndims (int ncid, int varid, int *ndimsp) +{ + return PIOc_inq_var(ncid, varid, NULL, NULL, ndimsp, NULL, NULL); +} + +/** + * @ingroup PIOc_inq_vardimid + * The PIO-C interface for the NetCDF function nc_inq_vardimid. + */ +int PIOc_inq_vardimid(int ncid, int varid, int *dimidsp) +{ + return PIOc_inq_var(ncid, varid, NULL, NULL, NULL, dimidsp, NULL); +} + +/** + * @ingroup PIOc_inq_varnatts + * The PIO-C interface for the NetCDF function nc_inq_varnatts. + */ +int PIOc_inq_varnatts (int ncid, int varid, int *nattsp) +{ + return PIOc_inq_var(ncid, varid, NULL, NULL, NULL, NULL, nattsp); +} + +/** + * @ingroup PIOc_inq_varid + * The PIO-C interface for the NetCDF function nc_inq_varid. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). * @param varid the variable ID. + * @param varidp a pointer that will get the variable id * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_get_att_double (int ncid, int varid, const char *name, double *ip) +int PIOc_inq_varid (int ncid, const char *name, int *varidp) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - errstr = NULL; - ierr = PIO_NOERR; + /* Caller must provide name. */ + if (!name || strlen(name) > NC_MAX_NAME) + return PIO_EINVAL; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Get file info based on ncid. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_GET_ATT_DOUBLE; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } + LOG((1, "PIOc_inq_varid ncid = %d name = %s", ncid, name)); - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_double(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_double(file->fh, varid, name, ip);; - } - break; -#endif + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ_VARID; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + int namelen; + namelen = strlen(name); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_double(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_inq_varid(file->fh, name, varidp);; +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq_varid(file->fh, name, varidp); +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_DOUBLE, ios->ioroot, ios->my_comm); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. Ignore NULL parameters. */ + if (varidp) + if ((mpierr = MPI_Bcast(varidp, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + return ierr; } /** - * @ingroup PIOc_set_fill - * The PIO-C interface for the NetCDF function nc_set_fill. + * @ingroup PIOc_inq_att + * The PIO-C interface for the NetCDF function nc_inq_att. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__datasets.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). + * @param varid the variable ID. + * @param xtypep a pointer that will get the type of the attribute. + * @param lenp a pointer that will get the number of values * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_set_fill (int ncid, int fillmode, int *old_modep) +int PIOc_inq_att(int ncid, int varid, const char *name, nc_type *xtypep, + PIO_Offset *lenp) { - int ierr; - int msg; - int mpierr; + int msg = PIO_MSG_INQ_ATT; iosystem_desc_t *ios; file_desc_t *file; - char *errstr; + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ + int ierr = PIO_NOERR; - errstr = NULL; - ierr = PIO_NOERR; + /* Caller must provide a name. */ + if (!name) + return PIO_EINVAL; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + LOG((1, "PIOc_inq_att ncid = %d varid = %d xtpyep = %d lenp = %d", + ncid, varid, xtypep, lenp)); + + /* Find file based on ncid. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_SET_FILL; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + char xtype_present = xtypep ? true : false; + char len_present = lenp ? true : false; + int namelen = strlen(name); + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&xtype_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&len_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_set_fill(file->fh, fillmode, old_modep);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_set_fill(file->fh, fillmode, old_modep);; - } - break; -#endif + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_set_fill(file->fh, fillmode, old_modep);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_inq_att(file->fh, varid, name, xtypep, lenp); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq_att(file->fh, varid, name, xtypep, (size_t *)lenp); +#endif /* _NETCDF */ + LOG((2, "PIOc_inq netcdf call returned %d", ierr)); } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; + } + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results. */ + if (!ierr) + { + if(xtypep) + if ((mpierr = MPI_Bcast(xtypep, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + if(lenp) + if ((mpierr = MPI_Bcast(lenp, 1, MPI_OFFSET, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); + return ierr; } /** - * @ingroup PIOc_def_var - * The PIO-C interface for the NetCDF function nc_def_var. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @param varidp a pointer that will get the variable id - * @return PIO_NOERR for success, error code otherwise. See - * PIOc_Set_File_Error_Handling + * @ingroup PIOc_inq_attlen + * The PIO-C interface for the NetCDF function nc_inq_attlen. */ -int PIOc_def_var (int ncid, const char *name, nc_type xtype, int ndims, - const int *dimidsp, int *varidp) +int PIOc_inq_attlen (int ncid, int varid, const char *name, PIO_Offset *lenp) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - int namelen; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_DEF_VAR; - - /* If async is in use, and this is not an IO tasks, then bcast the - * function parameters to the intercomm, where it will be read by - * the IO root task. */ - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - namelen = strlen(name); - printf("bcasting namelen = %d name = %s\n", namelen, name); - if (!ios->compmaster) - ios->compmaster = MPI_PROC_NULL; - mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&xtype, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&ndims, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast((void *)dimidsp, ndims, MPI_INT, ios->compmaster, ios->intercomm); - } - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_def_var(file->fh, name, xtype, ndims, dimidsp, varidp);; - break; - case PIO_IOTYPE_NETCDF4C: - if(ios->io_rank==0){ - ierr = nc_def_var(file->fh, name, xtype, ndims, dimidsp, varidp); - if(ierr == PIO_NOERR){ - ierr = nc_def_var_deflate(file->fh, *varidp, 0,1,1); - } - } - break; -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_def_var(file->fh, name, xtype, ndims, dimidsp, varidp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_def_var(file->fh, name, xtype, ndims, dimidsp, varidp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } + return PIOc_inq_att(ncid, varid, name, NULL, lenp); +} - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - mpierr = MPI_Bcast(varidp , 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; +/** + * @ingroup PIOc_inq_atttype + * The PIO-C interface for the NetCDF function nc_inq_atttype. + */ +int PIOc_inq_atttype(int ncid, int varid, const char *name, nc_type *xtypep) +{ + return PIOc_inq_att(ncid, varid, name, xtypep, NULL); } /** - * @ingroup PIOc_put_att_double - * The PIO-C interface for the NetCDF function nc_put_att_double. + * @ingroup PIOc_inq_attname + * The PIO-C interface for the NetCDF function nc_inq_attname. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand @@ -629,232 +980,273 @@ int PIOc_def_var (int ncid, const char *name, nc_type xtype, int ndims, * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). * @param varid the variable ID. + * @param attnum the attribute ID. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_put_att_double (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const double *op) +int PIOc_inq_attname(int ncid, int varid, int attnum, char *name) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - errstr = NULL; - ierr = PIO_NOERR; + LOG((1, "PIOc_inq_attname ncid = %d varid = %d attnum = %d", ncid, varid, + attnum)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_DOUBLE; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_double(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_double(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ_ATTNAME; + char name_present = name ? true : false; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&attnum, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&name_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_double(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_inq_attname(file->fh, varid, attnum, name);; +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq_attname(file->fh, varid, attnum, name);; +#endif /* _NETCDF */ + LOG((2, "PIOc_inq_attname netcdf call returned %d", ierr)); } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. Ignore NULL parameters. */ + if (!ierr) + if (name) + { + int namelen = strlen(name); + if ((mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + if ((mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->ioroot, + ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + } + return ierr; } /** - * @ingroup PIOc_inq_dim - * The PIO-C interface for the NetCDF function nc_inq_dim. + * @ingroup PIOc_inq_attid + * The PIO-C interface for the NetCDF function nc_inq_attid. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). - * @param lenp a pointer that will get the number of values + * @param varid the variable ID. + * @param idp a pointer that will get the id of the variable or attribute. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_inq_dim (int ncid, int dimid, char *name, PIO_Offset *lenp) +int PIOc_inq_attid(int ncid, int varid, const char *name, int *idp) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ + + /* User must provide name shorter than NC_MAX_NAME +1. */ + if (!name || strlen(name) > NC_MAX_NAME) + return PIO_EINVAL; + + LOG((1, "PIOc_inq_attid ncid = %d varid = %d name = %s", ncid, varid, name)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_DIM; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&dimid, 1, MPI_INT, ios->compmaster, ios->intercomm); - } - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_dim(file->fh, dimid, name, (size_t *)lenp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_dim(file->fh, dimid, name, (size_t *)lenp);; - } - break; -#endif + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ_ATTID; + int namelen = strlen(name); + char id_present = idp ? true : false; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((char *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&id_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_dim(file->fh, dimid, name, lenp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_inq_attid(file->fh, varid, name, idp);; +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq_attid(file->fh, varid, name, idp);; +#endif /* _NETCDF */ + LOG((2, "PIOc_inq_attname netcdf call returned %d", ierr)); } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(name) - { - int slen; - if(ios->iomaster) - slen = (int) strlen(name) + 1; - mpierr = MPI_Bcast(&slen, 1, MPI_INT, ios->ioroot, ios->my_comm); - mpierr = MPI_Bcast((void *)name, slen, MPI_CHAR, ios->ioroot, ios->my_comm); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results. */ + if (!ierr) + { + if (idp) + if ((mpierr = MPI_Bcast(idp, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); } - if(lenp != NULL) - mpierr = MPI_Bcast(lenp , 1, MPI_OFFSET, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); + return ierr; } /** - * @ingroup PIOc_get_att_uchar - * The PIO-C interface for the NetCDF function nc_get_att_uchar. + * @ingroup PIOc_rename_dim + * The PIO-C interface for the NetCDF function nc_rename_dim. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_get_att_uchar (int ncid, int varid, const char *name, unsigned char *ip) +int PIOc_rename_dim(int ncid, int dimid, const char *name) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ + + /* User must provide name of correct length. */ + if (!name || strlen(name) > NC_MAX_NAME) + return PIO_EINVAL; - errstr = NULL; - ierr = PIO_NOERR; + LOG((1, "PIOc_rename_dim ncid = %d dimid = %d name = %s", ncid, dimid, name)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_GET_ATT_UCHAR; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_RENAME_DIM; /** Message for async notification. */ + int namelen = strlen(name); + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&dimid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + LOG((2, "PIOc_rename_dim Bcast file->fh = %d dimid = %d namelen = %d name = %s", + file->fh, dimid, namelen, name)); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); } - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_uchar(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_uchar(file->fh, varid, name, ip);; - } - break; -#endif + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_uchar(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_rename_dim(file->fh, dimid, name); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_rename_dim(file->fh, dimid, name);; +#endif /* _NETCDF */ + LOG((2, "PIOc_inq netcdf call returned %d", ierr)); } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_UNSIGNED_CHAR, ios->ioroot, ios->my_comm); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + return ierr; } /** - * @ingroup PIOc_inq_var_fill - * The PIO-C interface for the NetCDF function nc_inq_var_fill. + * @ingroup PIOc_rename_var + * The PIO-C interface for the NetCDF function nc_rename_var. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand @@ -866,69 +1258,82 @@ int PIOc_get_att_uchar (int ncid, int varid, const char *name, unsigned char *ip * @param varid the variable ID. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_inq_var_fill (int ncid, int varid, int *no_fill, void *fill_value) +int PIOc_rename_var(int ncid, int varid, const char *name) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ + + /* User must provide name of correct length. */ + if (!name || strlen(name) > NC_MAX_NAME) + return PIO_EINVAL; - errstr = NULL; - ierr = PIO_NOERR; + LOG((1, "PIOc_rename_var ncid = %d varid = %d name = %s", ncid, varid, name)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_VAR_FILL; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_RENAME_VAR; /** Message for async notification. */ + int namelen = strlen(name); + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + LOG((2, "PIOc_rename_var Bcast file->fh = %d varid = %d namelen = %d name = %s", + file->fh, varid, namelen, name)); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); } - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_var_fill(file->fh, varid, no_fill, fill_value);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_var_fill(file->fh, varid, no_fill, fill_value);; - } - break; -#endif + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_var_fill(file->fh, varid, no_fill, fill_value);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_rename_var(file->fh, varid, name); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_rename_var(file->fh, varid, name);; +#endif /* _NETCDF */ + LOG((2, "PIOc_inq netcdf call returned %d", ierr)); } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - mpierr = MPI_Bcast(fill_value, 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + return ierr; } /** - * @ingroup PIOc_inq_attid - * The PIO-C interface for the NetCDF function nc_inq_attid. + * @ingroup PIOc_rename_att + * The PIO-C interface for the NetCDF function nc_rename_att. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand @@ -938,617 +1343,444 @@ int PIOc_inq_var_fill (int ncid, int varid, int *no_fill, void *fill_value) * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). * @param varid the variable ID. - * @param idp a pointer that will get the id of the variable or attribute. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @return PIO_NOERR for success, error code otherwise. See + * PIOc_Set_File_Error_Handling */ -int PIOc_inq_attid (int ncid, int varid, const char *name, int *idp) +int PIOc_rename_att (int ncid, int varid, const char *name, + const char *newname) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI functions. */ - errstr = NULL; - ierr = PIO_NOERR; + /* User must provide names of correct length. */ + if (!name || strlen(name) > NC_MAX_NAME || + !newname || strlen(newname) > NC_MAX_NAME) + return PIO_EINVAL; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + LOG((1, "PIOc_rename_att ncid = %d varid = %d name = %s newname = %s", + ncid, varid, name, newname)); + + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_ATTID; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_RENAME_ATT; /** Message for async notification. */ + int namelen = strlen(name); + int newnamelen = strlen(newname); + + if (ios->compmaster) + mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((char *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&newnamelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((char *)newname, newnamelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_attid(file->fh, varid, name, idp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_attid(file->fh, varid, name, idp);; - } - break; -#endif + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_attid(file->fh, varid, name, idp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_rename_att(file->fh, varid, name, newname); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_rename_att(file->fh, varid, name, newname); +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - mpierr = MPI_Bcast(idp , 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + + LOG((2, "PIOc_rename_att succeeded")); return ierr; } /** - * @ingroup PIOc_inq_vartype - * The PIO-C interface for the NetCDF function nc_inq_vartype. + * @ingroup PIOc_del_att + * The PIO-C interface for the NetCDF function nc_del_att. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). * @param varid the variable ID. - * @param xtypep a pointer that will get the type of the attribute. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_inq_vartype (int ncid, int varid, nc_type *xtypep) +int PIOc_del_att(int ncid, int varid, const char *name) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI functions. */ - errstr = NULL; - ierr = PIO_NOERR; + /* User must provide name of correct length. */ + if (!name || strlen(name) > NC_MAX_NAME) + return PIO_EINVAL; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_VARTYPE; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&file->fh,1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); - } + LOG((1, "PIOc_del_att ncid = %d varid = %d name = %s", ncid, varid, name)); + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; + ios = file->iosystem; - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_vartype(file->fh, varid, xtypep);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_vartype(file->fh, varid, xtypep);; - } - break; -#endif + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_DEL_ATT; + int namelen = strlen(name); /** Length of name string. */ + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((char *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_vartype(file->fh, varid, xtypep);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_del_att(file->fh, varid, name); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_del_att(file->fh, varid, name); +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (xtypep) - mpierr = MPI_Bcast(xtypep, 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + + LOG((2, "PIOc_del_att succeeded")); return ierr; } /** - * @ingroup PIOc_put_att_schar - * The PIO-C interface for the NetCDF function nc_put_att_schar. + * @ingroup PIOc_set_fill + * The PIO-C interface for the NetCDF function nc_set_fill. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__datasets.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_put_att_schar (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const signed char *op) +int PIOc_set_fill (int ncid, int fillmode, int *old_modep) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI functions. */ - errstr = NULL; - ierr = PIO_NOERR; + LOG((1, "PIOc_set_fill ncid = %d fillmode = %d old_modep = %d", ncid, fillmode, + old_modep)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_SCHAR; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_SET_FILL; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); } - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_schar(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_schar(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_schar(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_set_fill(file->fh, fillmode, old_modep); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_set_fill(file->fh, fillmode, old_modep); +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + + LOG((2, "PIOc_set_fill succeeded")); return ierr; } -/** - * @ingroup PIOc_inq_vardimid - * The PIO-C interface for the NetCDF function nc_inq_vardimid. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_vardimid (int ncid, int varid, int *dimidsp) +/** This is an internal function that handles both PIOc_enddef and + * PIOc_redef. + * @param ncid the ncid of the file to enddef or redef + * @param is_enddef set to non-zero for enddef, 0 for redef. + * @returns PIO_NOERR on success, error code on failure. */ +int pioc_change_def(int ncid, int is_enddef) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI functions. */ - errstr = NULL; - ierr = PIO_NOERR; + LOG((1, "pioc_change_def ncid = %d is_enddef = %d", ncid, is_enddef)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_VARDIMID; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); - } + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = is_enddef ? PIO_MSG_ENDDEF : PIO_MSG_REDEF; + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_vardimid(file->fh, varid, dimidsp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_vardimid(file->fh, varid, dimidsp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_vardimid(file->fh, varid, dimidsp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { +#ifdef _PNETCDF + if (file->iotype == PIO_IOTYPE_PNETCDF) + if (is_enddef) + ierr = ncmpi_enddef(file->fh); + else + ierr = ncmpi_redef(file->fh); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + if (is_enddef) + ierr = nc_enddef(file->fh); + else + ierr = nc_redef(file->fh); +#endif /* _NETCDF */ } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (!ierr && dimidsp) + + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) { - int ndims; - PIOc_inq_varndims(file->fh, varid, &ndims); - mpierr = MPI_Bcast(dimidsp , ndims, MPI_INT, ios->ioroot, ios->my_comm); + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + return ierr; } /** - * @ingroup PIOc_get_att_ushort - * The PIO-C interface for the NetCDF function nc_get_att_ushort. + * @ingroup PIOc_enddef + * The PIO-C interface for the NetCDF function nc_enddef. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__datasets.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_get_att_ushort (int ncid, int varid, const char *name, unsigned short *ip) +int PIOc_enddef(int ncid) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_USHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_ushort(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_ushort(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_ushort(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_UNSIGNED_SHORT, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; + return pioc_change_def(ncid, 1); } /** - * @ingroup PIOc_inq_varid - * The PIO-C interface for the NetCDF function nc_inq_varid. + * @ingroup PIOc_redef + * The PIO-C interface for the NetCDF function nc_redef. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__datasets.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @param varidp a pointer that will get the variable id * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_inq_varid (int ncid, const char *name, int *varidp) +int PIOc_redef(int ncid) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_VARID; - - int my_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - printf("%d PIOc_inq_varid ncid = %d name = %s\n", my_rank, ncid, name); - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - printf("%d PIOc_inq_varid BCast ncid = %d\n", my_rank, ncid); - mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); - int namelen; - namelen = strlen(name); - printf("%d PIOc_inq_varid BCast namelen = %d\n", my_rank, namelen); - mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq_varid BCast name = %s\n", my_rank, name); - mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); - printf("%d PIOc_inq_varid BCast done\n", my_rank); - } - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_varid(file->fh, name, varidp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_varid(file->fh, name, varidp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_varid(file->fh, name, varidp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (varidp) - mpierr = MPI_Bcast(varidp, 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; + return pioc_change_def(ncid, 0); } /** - * @ingroup PIOc_inq_attlen - * The PIO-C interface for the NetCDF function nc_inq_attlen. + * @ingroup PIOc_def_dim + * The PIO-C interface for the NetCDF function nc_def_dim. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @param lenp a pointer that will get the number of values + * @param idp a pointer that will get the id of the variable or attribute. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_inq_attlen (int ncid, int varid, const char *name, PIO_Offset *lenp) +int PIOc_def_dim (int ncid, const char *name, PIO_Offset len, int *idp) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_ATTLEN; + /* User must provide name. */ + if (!name || strlen(name) > NC_MAX_NAME) + return PIO_EINVAL; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } + LOG((1, "PIOc_def_dim ncid = %d name = %s len = %d", ncid, name, len)); + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; + ios = file->iosystem; - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_attlen(file->fh, varid, name, (size_t *)lenp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_attlen(file->fh, varid, name, (size_t *)lenp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_attlen(file->fh, varid, name, lenp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_DEF_DIM; + int namelen = strlen(name); - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - mpierr = MPI_Bcast(lenp , 1, MPI_OFFSET, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; -} + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); -/** - * @ingroup PIOc_inq_atttype - * The PIO-C interface for the NetCDF function nc_inq_atttype. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @param xtypep a pointer that will get the type of the attribute. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_atttype (int ncid, int varid, const char *name, nc_type *xtypep) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + if (!mpierr) + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - errstr = NULL; - ierr = PIO_NOERR; + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&len, 1, MPI_INT, ios->compmaster, ios->intercomm); + } - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_ATTTYPE; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_atttype(file->fh, varid, name, xtypep);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_atttype(file->fh, varid, name, xtypep);; - } - break; -#endif + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_atttype(file->fh, varid, name, xtypep);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_def_dim(file->fh, name, len, idp);; +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_def_dim(file->fh, name, (size_t)len, idp); +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr2, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - mpierr = MPI_Bcast(xtypep , 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. Ignore NULL parameters. */ + if (!ierr) + if (idp) + if ((mpierr = MPI_Bcast(idp , 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + return ierr; } /** - * @ingroup PIOc_rename_var - * The PIO-C interface for the NetCDF function nc_rename_var. + * @ingroup PIOc_def_var + * The PIO-C interface for the NetCDF function nc_def_var. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand @@ -1558,317 +1790,318 @@ int PIOc_inq_atttype (int ncid, int varid, const char *name, nc_type *xtypep) * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @param varidp a pointer that will get the variable id + * @return PIO_NOERR for success, error code otherwise. See + * PIOc_Set_File_Error_Handling */ -int PIOc_rename_var (int ncid, int varid, const char *name) +int PIOc_def_var (int ncid, const char *name, nc_type xtype, int ndims, + const int *dimidsp, int *varidp) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_RENAME_VAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_rename_var(file->fh, varid, name);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_rename_var(file->fh, varid, name);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_rename_var(file->fh, varid, name);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + /* User must provide name and storage for varid. */ + if (!name || !varidp || strlen(name) > NC_MAX_NAME) + { + check_netcdf(file, PIO_EINVAL, __FILE__, __LINE__); + return PIO_EINVAL; } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Get the file information. */ + if (!(file = pio_get_file_from_id(ncid))) + { + check_netcdf(file, PIO_EBADID, __FILE__, __LINE__); + return PIO_EBADID; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_natts - * The PIO-C interface for the NetCDF function nc_inq_natts. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_natts (int ncid, int *ngattsp) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_INQ_NATTS; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ + /* If using async, and not an IO task, then send parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_DEF_VAR; + int namelen = strlen(name); + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&(ncid), 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&xtype, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&ndims, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)dimidsp, ndims, MPI_INT, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { +#ifdef _PNETCDF + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_def_var(ncid, name, xtype, ndims, dimidsp, varidp); +#endif /* _PNETCDF */ #ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_def_var(ncid, name, xtype, ndims, dimidsp, varidp); #ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_natts(file->fh, ngattsp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_natts(file->fh, ngattsp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_natts(file->fh, ngattsp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + /* For netCDF-4 serial files, turn on compression for this variable. */ + if (!ierr && file->iotype == PIO_IOTYPE_NETCDF4C) + ierr = nc_def_var_deflate(ncid, *varidp, 0, 1, 1); + + /* For netCDF-4 parallel files, set parallel access to collective. */ + if (!ierr && file->iotype == PIO_IOTYPE_NETCDF4P) + ierr = nc_var_par_access(ncid, *varidp, NC_COLLECTIVE); +#endif /* _NETCDF4 */ +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (ngattsp) - mpierr = MPI_Bcast(ngattsp,1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results. */ + if (!ierr) + if (varidp) + if ((mpierr = MPI_Bcast(varidp , 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + return ierr; } /** - * @ingroup PIOc_put_att_ulonglong - * The PIO-C interface for the NetCDF function nc_put_att_ulonglong. + * @ingroup PIOc_inq_var_fill + * The PIO-C interface for the NetCDF function nc_inq_var_fill. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). * @param varid the variable ID. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_put_att_ulonglong (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const unsigned long long *op) +int PIOc_inq_var_fill(int ncid, int varid, int *no_fill, void *fill_valuep) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - errstr = NULL; - ierr = PIO_NOERR; + LOG((1, "PIOc_inq ncid = %d", ncid)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_ULONGLONG; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_INQ_VAR_FILL; + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_ulonglong(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_ulonglong(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif + if (!mpierr) + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_ulonglong(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_inq_var_fill(file->fh, varid, no_fill, fill_valuep); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_inq_var_fill(file->fh, varid, no_fill, fill_valuep); +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. Ignore NULL parameters. */ + if (!ierr) + if (fill_valuep) + if ((mpierr = MPI_Bcast(fill_valuep, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + return ierr; } /** - * @ingroup PIOc_inq_var - * The PIO-C interface for the NetCDF function nc_inq_var. + * @ingroup PIOc_get_att + * The PIO-C interface for the NetCDF function nc_get_att. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html + * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html * * @param ncid the ncid of the open file, obtained from * PIOc_openfile() or PIOc_createfile(). * @param varid the variable ID. - * @param xtypep a pointer that will get the type of the attribute. - * @param nattsp a pointer that will get the number of attributes - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @return PIO_NOERR for success, error code otherwise. See + * PIOc_Set_File_Error_Handling */ -int PIOc_inq_var (int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, - int *dimidsp, int *nattsp) +int PIOc_get_att(int ncid, int varid, const char *name, void *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ + PIO_Offset attlen, typelen; + nc_type atttype; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_VAR; + /* User must provide a name and destination pointer. */ + if (!name || !ip || strlen(name) > NC_MAX_NAME) + return PIO_EINVAL; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); - } + LOG((1, "PIOc_get_att ncid %d varid %d name %s", ncid, varid, name)); + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; + ios = file->iosystem; - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_var(file->fh, varid, name, xtypep, ndimsp, dimidsp, nattsp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_var(file->fh, varid, name, xtypep, ndimsp, dimidsp, nattsp);; - } - break; -#endif + /* Run these on all tasks if async is not in use, but only on + * non-IO tasks if async is in use. */ + if (!ios->async_interface || !ios->ioproc) + { + /* Get the type and length of the attribute. */ + if ((ierr = PIOc_inq_att(file->fh, varid, name, &atttype, &attlen))) + { + check_netcdf(file, ierr, __FILE__, __LINE__); + return ierr; + } + + /* Get the length (in bytes) of the type. */ + if ((ierr = PIOc_inq_type(file->fh, atttype, NULL, &typelen))) + { + check_netcdf(file, ierr, __FILE__, __LINE__); + return ierr; + } + } + + /* If async is in use, and this is not an IO task, bcast the + * parameters and the attribute and type information we fetched. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_GET_ATT; + + /* Send the message to IO master. */ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + + /* Send the function parameters. */ + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + int namelen = strlen(name); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&file->iotype, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&atttype, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&attlen, 1, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, ios->compmaster, ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + + /* Broadcast values currently only known on computation tasks to IO tasks. */ + LOG((2, "PIOc_get_att bcast from comproot = %d attlen = %d typelen = %d", ios->comproot, attlen, typelen)); + if ((mpierr = MPI_Bcast(&attlen, 1, MPI_OFFSET, ios->comproot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + if ((mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, ios->comproot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + LOG((2, "PIOc_get_att bcast complete attlen = %d typelen = %d", attlen, typelen)); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_var(file->fh, varid, name, xtypep, ndimsp, dimidsp, nattsp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_get_att(file->fh, varid, name, ip); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_get_att(file->fh, varid, name, ip); +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (xtypep) - mpierr = MPI_Bcast(xtypep, 1, MPI_INT, ios->ioroot, ios->my_comm); - if (ndimsp) + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) { - mpierr = MPI_Bcast(ndimsp, 1, MPI_OFFSET, ios->ioroot, ios->my_comm); - file->varlist[varid].ndims = (*ndimsp); - } - if (nattsp) - mpierr = MPI_Bcast(nattsp, 1, MPI_INT, ios->ioroot, ios->my_comm); - if (name) - { - int slen; - if(ios->iomaster) - slen = (int) strlen(name) + 1; - mpierr = MPI_Bcast(&slen, 1, MPI_INT, ios->ioroot, ios->my_comm); - mpierr = MPI_Bcast((void *)name, slen, MPI_CHAR, ios->ioroot, ios->my_comm); + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - if (dimidsp) + check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Broadcast results to all tasks. */ + if (!ierr) { - int ndims; - PIOc_inq_varndims(file->fh, varid, &ndims); - mpierr = MPI_Bcast(dimidsp, ndims, MPI_INT, ios->ioroot, ios->my_comm); + if ((mpierr = MPI_Bcast(ip, (int)attlen * typelen, MPI_BYTE, ios->ioroot, + ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; + } } - if(errstr != NULL) free(errstr); return ierr; } /** - * @ingroup PIOc_rename_att - * The PIO-C interface for the NetCDF function nc_rename_att. + * @ingroup PIOc_put_att + * The PIO-C interface for the NetCDF function nc_put_att. * * This routine is called collectively by all tasks in the communicator * ios.union_comm. For more information on the underlying NetCDF commmand @@ -1880,2655 +2113,347 @@ int PIOc_inq_var (int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, * @param varid the variable ID. * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_rename_att (int ncid, int varid, const char *name, const char *newname) +int PIOc_put_att(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const void *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + PIO_Offset typelen; /** Length (in bytes) of the type. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ - errstr = NULL; - ierr = PIO_NOERR; + LOG((1, "PIOc_put_att ncid = %d varid = %d name = %s", ncid, varid, name)); - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; ios = file->iosystem; - msg = PIO_MSG_RENAME_ATT; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + /* Run these on all tasks if async is not in use, but only on + * non-IO tasks if async is in use. */ + if (!ios->async_interface || !ios->ioproc) + { + /* Get the length (in bytes) of the type. */ + if ((ierr = PIOc_inq_type(ncid, xtype, NULL, &typelen))) + { + check_netcdf(file, ierr, __FILE__, __LINE__); + return ierr; + } + LOG((2, "PIOc_put_att typelen = %d", ncid, typelen)); } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_rename_att(file->fh, varid, name, newname);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_rename_att(file->fh, varid, name, newname);; - } - break; -#endif + + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_PUT_ATT; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm); + + if (!mpierr) + mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + int namelen = strlen(name); + if (!mpierr) + mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&xtype, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&len, 1, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast((void *)op, len * typelen, MPI_BYTE, ios->compmaster, + ios->intercomm); + LOG((2, "PIOc_put_att finished bcast ncid = %d varid = %d namelen = %d name = %s " + "len = %d typelen = %d", file->fh, varid, namelen, name, len, typelen)); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + + /* Broadcast values currently only known on computation tasks to IO tasks. */ + LOG((2, "PIOc_put_att bcast from comproot = %d typelen = %d", ios->comproot, typelen)); + if ((mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, ios->comproot, ios->my_comm))) + check_mpi(file, mpierr, __FILE__, __LINE__); + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_rename_att(file->fh, varid, name, newname);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } + if (file->iotype == PIO_IOTYPE_PNETCDF) + ierr = ncmpi_put_att(file->fh, varid, name, xtype, len, op); +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + ierr = nc_put_att(file->fh, varid, name, xtype, (size_t)len, op); +#endif /* _NETCDF */ } - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + { + check_mpi(file, mpierr, __FILE__, __LINE__); + return PIO_EIO; } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); + check_netcdf(file, ierr, __FILE__, __LINE__); + return ierr; } /** - * @ingroup PIOc_put_att_ushort - * The PIO-C interface for the NetCDF function nc_put_att_ushort. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_get_att_double + * The PIO-C interface for the NetCDF function nc_get_att_double. */ -int PIOc_put_att_ushort (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const unsigned short *op) +int PIOc_get_att_double(int ncid, int varid, const char *name, double *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_USHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_ushort(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_ushort(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_ushort(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** - * @ingroup PIOc_inq_dimid - * The PIO-C interface for the NetCDF function nc_inq_dimid. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param idp a pointer that will get the id of the variable or attribute. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_get_att_uchar + * The PIO-C interface for the NetCDF function nc_get_att_uchar. */ -int PIOc_inq_dimid (int ncid, const char *name, int *idp) +int PIOc_get_att_uchar (int ncid, int varid, const char *name, unsigned char *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_DIMID; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); - int namelen; - if (ios->iomaster) - namelen = strlen(name); - mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_dimid(file->fh, name, idp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_dimid(file->fh, name, idp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_dimid(file->fh, name, idp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (idp) - mpierr = MPI_Bcast(idp, 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** - * @ingroup PIOc_put_att_text - * The PIO-C interface for the NetCDF function nc_put_att_text. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_get_att_ushort + * The PIO-C interface for the NetCDF function nc_get_att_ushort. */ -int PIOc_put_att_text (int ncid, int varid, const char *name, PIO_Offset len, const char *op) +int PIOc_get_att_ushort (int ncid, int varid, const char *name, unsigned short *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_TEXT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_text(file->fh, varid, name, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_text(file->fh, varid, name, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_text(file->fh, varid, name, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** * @ingroup PIOc_get_att_uint * The PIO-C interface for the NetCDF function nc_get_att_uint. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ int PIOc_get_att_uint (int ncid, int varid, const char *name, unsigned int *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_UINT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_uint(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_uint(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_uint(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_UNSIGNED, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_format - * The PIO-C interface for the NetCDF function nc_inq_format. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__datasets.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param formatp a pointer that will get the file format - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_format (int ncid, int *formatp) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_FORMAT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_format(file->fh, formatp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_format(file->fh, formatp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_format(file->fh, formatp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - mpierr = MPI_Bcast(formatp , 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** * @ingroup PIOc_get_att_long * The PIO-C interface for the NetCDF function nc_get_att_long. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ int PIOc_get_att_long (int ncid, int varid, const char *name, long *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_LONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_long(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_long(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_long(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_LONG, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_attname - * The PIO-C interface for the NetCDF function nc_inq_attname. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @param attnum the attribute ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_attname (int ncid, int varid, int attnum, char *name) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_ATTNAME; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_attname(file->fh, varid, attnum, name);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_attname(file->fh, varid, attnum, name);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_attname(file->fh, varid, attnum, name);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(name != NULL){ - int slen; - if(ios->iomaster) - slen = (int) strlen(name) + 1; - mpierr = MPI_Bcast(&slen, 1, MPI_INT, ios->ioroot, ios->my_comm); - mpierr = MPI_Bcast((void *)name, slen, MPI_CHAR, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_att - * The PIO-C interface for the NetCDF function nc_inq_att. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @param xtypep a pointer that will get the type of the attribute. - * @param lenp a pointer that will get the number of values - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_att (int ncid, int varid, const char *name, nc_type *xtypep, PIO_Offset *lenp) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_ATT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_att(file->fh, varid, name, xtypep, (size_t *)lenp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_att(file->fh, varid, name, xtypep, (size_t *)lenp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_att(file->fh, varid, name, xtypep, lenp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(xtypep != NULL) mpierr = MPI_Bcast(xtypep , 1, MPI_INT, ios->ioroot, ios->my_comm); - if(lenp != NULL) mpierr = MPI_Bcast(lenp , 1, MPI_OFFSET, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** - * @ingroup PIOc_put_att_long - * The PIO-C interface for the NetCDF function nc_put_att_long. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_get_att_ubyte + * The PIO-C interface for the NetCDF function nc_get_att_ubyte. */ -int PIOc_put_att_long (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const long *op) +int PIOc_get_att_ubyte (int ncid, int varid, const char *name, unsigned char *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_LONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_long(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_long(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_long(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** - * @ingroup PIOc_inq_unlimdim - * The PIO-C interface for the NetCDF function nc_inq_unlimdim. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_get_att_text + * The PIO-C interface for the NetCDF function nc_get_att_text. */ -int PIOc_inq_unlimdim (int ncid, int *unlimdimidp) +int PIOc_get_att_text (int ncid, int varid, const char *name, char *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_UNLIMDIM; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_unlimdim(file->fh, unlimdimidp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_unlimdim(file->fh, unlimdimidp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_unlimdim(file->fh, unlimdimidp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (unlimdimidp) - mpierr = MPI_Bcast(unlimdimidp,1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** - * @ingroup PIOc_get_att_float - * The PIO-C interface for the NetCDF function nc_get_att_float. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_get_att_float (int ncid, int varid, const char *name, float *ip) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_FLOAT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_float(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_float(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_float(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_FLOAT, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_ndims - * The PIO-C interface for the NetCDF function nc_inq_ndims. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_ndims (int ncid, int *ndimsp) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_NDIMS; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_ndims(file->fh, ndimsp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_ndims(file->fh, ndimsp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_ndims(file->fh, ndimsp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (ndimsp) - mpierr = MPI_Bcast(ndimsp , 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_put_att_int - * The PIO-C interface for the NetCDF function nc_put_att_int. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_put_att_int (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_INT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_int(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_int(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_int(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_nvars - * The PIO-C interface for the NetCDF function nc_inq_nvars. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_nvars (int ncid, int *nvarsp) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_NVARS; - - if(ios->async_interface && ! ios->ioproc){ - if(!ios->comp_rank) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_nvars(file->fh, nvarsp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_nvars(file->fh, nvarsp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_nvars(file->fh, nvarsp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (nvarsp) - mpierr = MPI_Bcast(nvarsp,1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_enddef - * The PIO-C interface for the NetCDF function nc_enddef. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__datasets.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_enddef (int ncid) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_ENDDEF; - - if(ios->async_interface && ! ios->ioproc){ - if(!ios->comp_rank) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - printf("PIOc_enddef file->fh = %d\n", file->fh); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_enddef(file->fh);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_enddef(file->fh);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_enddef(file->fh);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_put_att_uchar - * The PIO-C interface for the NetCDF function nc_put_att_uchar. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_put_att_uchar (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const unsigned char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_UCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_uchar(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_uchar(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_uchar(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_put_att_longlong - * The PIO-C interface for the NetCDF function nc_put_att_longlong. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_put_att_longlong (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const long long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_LONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_longlong(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_longlong(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_longlong(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_varnatts - * The PIO-C interface for the NetCDF function nc_inq_varnatts. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @param nattsp a pointer that will get the number of attributes - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_varnatts (int ncid, int varid, int *nattsp) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_VARNATTS; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&file->fh, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_varnatts(file->fh, varid, nattsp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_varnatts(file->fh, varid, nattsp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_varnatts(file->fh, varid, nattsp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (nattsp) - mpierr = MPI_Bcast(nattsp, 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_get_att_ubyte - * The PIO-C interface for the NetCDF function nc_get_att_ubyte. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_get_att_ubyte (int ncid, int varid, const char *name, unsigned char *ip) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_UBYTE; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_ubyte(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_ubyte(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_ubyte(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_BYTE, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_get_att_text - * The PIO-C interface for the NetCDF function nc_get_att_text. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_get_att_text (int ncid, int varid, const char *name, char *ip) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_TEXT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_text(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_text(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_text(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_CHAR, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_del_att - * The PIO-C interface for the NetCDF function nc_del_att. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_del_att (int ncid, int varid, const char *name) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_DEL_ATT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_del_att(file->fh, varid, name);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_del_att(file->fh, varid, name);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_del_att(file->fh, varid, name);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_dimlen - * The PIO-C interface for the NetCDF function nc_inq_dimlen. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param lenp a pointer that will get the number of values - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_dimlen (int ncid, int dimid, PIO_Offset *lenp) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_DIMLEN; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&dimid, 1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_dimlen(file->fh, dimid, (size_t *)lenp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_dimlen(file->fh, dimid, (size_t *)lenp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_dimlen(file->fh, dimid, lenp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (lenp) - mpierr = MPI_Bcast(lenp, 1, MPI_OFFSET, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_get_att_schar - * The PIO-C interface for the NetCDF function nc_get_att_schar. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_get_att_schar (int ncid, int varid, const char *name, signed char *ip) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_SCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_schar(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_schar(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_schar(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_CHAR, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_get_att_ulonglong - * The PIO-C interface for the NetCDF function nc_get_att_ulonglong. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_get_att_ulonglong (int ncid, int varid, const char *name, unsigned long long *ip) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_ULONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_ulonglong(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_ulonglong(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_ulonglong(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_UNSIGNED_LONG_LONG, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_varndims - * The PIO-C interface for the NetCDF function nc_inq_varndims. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_varndims (int ncid, int varid, int *ndimsp) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_VARNDIMS; - if(file->varlist[varid].ndims > 0){ - (*ndimsp) = file->varlist[varid].ndims; - return PIO_NOERR; - } - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&file->fh,1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&varid,1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_varndims(file->fh, varid, ndimsp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_varndims(file->fh, varid, ndimsp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_varndims(file->fh, varid, ndimsp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if (ndimsp) - { - mpierr = MPI_Bcast(ndimsp,1, MPI_INT, ios->ioroot, ios->my_comm); - file->varlist[varid].ndims = (*ndimsp); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_inq_varname - * The PIO-C interface for the NetCDF function nc_inq_varname. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_inq_varname (int ncid, int varid, char *name) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_INQ_VARNAME; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&file->fh,1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_inq_varname(file->fh, varid, name);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_inq_varname(file->fh, varid, name);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_inq_varname(file->fh, varid, name);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(name != NULL){ - int slen; - if(ios->iomaster) - slen = (int) strlen(name) + 1; - mpierr = MPI_Bcast(&slen, 1, MPI_INT, ios->ioroot, ios->my_comm); - mpierr = MPI_Bcast((void *)name, slen, MPI_CHAR, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_def_dim - * The PIO-C interface for the NetCDF function nc_def_dim. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__dimensions.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param idp a pointer that will get the id of the variable or attribute. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling - */ -int PIOc_def_dim (int ncid, const char *name, PIO_Offset len, int *idp) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - int namelen; - - errstr = NULL; - ierr = PIO_NOERR; - - int my_rank; - MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); - printf("%d PIOc_def_dim ncid = %d name = %s len = %d\n", my_rank, - ncid, name, len); - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_DEF_DIM; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - namelen = strlen(name); - printf("bcasting namelen = %d name = %s len = %d\n", namelen, name, len); - if (!ios->compmaster) - ios->compmaster = MPI_PROC_NULL; - mpierr = MPI_Bcast(&namelen, 1, MPI_INT, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast((void *)name, namelen + 1, MPI_CHAR, ios->compmaster, ios->intercomm); - mpierr = MPI_Bcast(&len, 1, MPI_INT, ios->compmaster, ios->intercomm); - } - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_def_dim(file->fh, name, (size_t)len, idp);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_def_dim(file->fh, name, (size_t)len, idp);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_def_dim(file->fh, name, len, idp);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - mpierr = MPI_Bcast(idp , 1, MPI_INT, ios->ioroot, ios->my_comm); - if(errstr != NULL) free(errstr); - return ierr; -} - -/** - * @ingroup PIOc_put_att_uint - * The PIO-C interface for the NetCDF function nc_put_att_uint. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_get_att_schar + * The PIO-C interface for the NetCDF function nc_get_att_schar. */ -int PIOc_put_att_uint (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const unsigned int *op) +int PIOc_get_att_schar (int ncid, int varid, const char *name, signed char *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_UINT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_uint(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_uint(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_uint(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } + return PIOc_get_att(ncid, varid, name, (void *)ip); +} - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; +/** + * @ingroup PIOc_get_att_ulonglong + * The PIO-C interface for the NetCDF function nc_get_att_ulonglong. + */ +int PIOc_get_att_ulonglong (int ncid, int varid, const char *name, unsigned long long *ip) +{ + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** * @ingroup PIOc_get_att_short * The PIO-C interface for the NetCDF function nc_get_att_short. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ int PIOc_get_att_short (int ncid, int varid, const char *name, short *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_SHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_short(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_short(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_short(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_SHORT, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** - * @ingroup PIOc_redef - * The PIO-C interface for the NetCDF function nc_redef. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__datasets.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_get_att_int + * The PIO-C interface for the NetCDF function nc_get_att_int. */ -int PIOc_redef (int ncid) +int PIOc_get_att_int(int ncid, int varid, const char *name, int *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_REDEF; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_redef(file->fh);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_redef(file->fh);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_redef(file->fh);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** - * @ingroup PIOc_put_att_ubyte - * The PIO-C interface for the NetCDF function nc_put_att_ubyte. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_get_att_longlong + * The PIO-C interface for the NetCDF function nc_get_att_longlong. */ -int PIOc_put_att_ubyte (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const unsigned char *op) +int PIOc_get_att_longlong(int ncid, int varid, const char *name, long long *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_UBYTE; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_ubyte(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_ubyte(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_ubyte(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** - * @ingroup PIOc_get_att_int - * The PIO-C interface for the NetCDF function nc_get_att_int. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_get_att_float + * The PIO-C interface for the NetCDF function nc_get_att_float. */ -int PIOc_get_att_int (int ncid, int varid, const char *name, int *ip) +int PIOc_get_att_float (int ncid, int varid, const char *name, float *ip) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_INT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_int(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_int(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_int(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_INT, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; + return PIOc_get_att(ncid, varid, name, (void *)ip); } /** - * @ingroup PIOc_get_att_longlong - * The PIO-C interface for the NetCDF function nc_get_att_longlong. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling + * @ingroup PIOc_put_att_schar + * The PIO-C interface for the NetCDF function nc_put_att_schar. */ -int PIOc_get_att_longlong (int ncid, int varid, const char *name, long long *ip) +int PIOc_put_att_schar(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const signed char *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; + return PIOc_put_att(ncid, varid, name, xtype, len, op); +} - errstr = NULL; - ierr = PIO_NOERR; +/** + * @ingroup PIOc_put_att_long + * The PIO-C interface for the NetCDF function nc_put_att_long. + */ +int PIOc_put_att_long(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const long *op) +{ + return PIOc_put_att(ncid, varid, name, NC_CHAR, len, op); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_GET_ATT_LONGLONG; +/** + * @ingroup PIOc_put_att_int + * The PIO-C interface for the NetCDF function nc_put_att_int. + */ +int PIOc_put_att_int(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const int *op) +{ + return PIOc_put_att(ncid, varid, name, xtype, len, op); +} - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } +/** + * @ingroup PIOc_put_att_uchar + * The PIO-C interface for the NetCDF function nc_put_att_uchar. + */ +int PIOc_put_att_uchar(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const unsigned char *op) +{ + return PIOc_put_att(ncid, varid, name, xtype, len, op); +} +/** + * @ingroup PIOc_put_att_longlong + * The PIO-C interface for the NetCDF function nc_put_att_longlong. + */ +int PIOc_put_att_longlong(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const long long *op) +{ + return PIOc_put_att(ncid, varid, name, xtype, len, op); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_get_att_longlong(file->fh, varid, name, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_get_att_longlong(file->fh, varid, name, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_get_att_longlong(file->fh, varid, name, ip);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +/** + * @ingroup PIOc_put_att_uint + * The PIO-C interface for the NetCDF function nc_put_att_uint. + */ +int PIOc_put_att_uint(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const unsigned int *op) +{ + return PIOc_put_att(ncid, varid, name, xtype, len, op); +} - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(name)+strlen(__FILE__) + 40)* sizeof(char)); - sprintf(errstr,"name %s in file %s",name,__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(ierr == PIO_NOERR){ - PIO_Offset attlen; - PIOc_inq_attlen(file->fh, varid, name, &attlen); - mpierr = MPI_Bcast(ip , (int) attlen, MPI_LONG_LONG, ios->ioroot, ios->my_comm); - } - if(errstr != NULL) free(errstr); - return ierr; +/** + * @ingroup PIOc_put_att_ubyte + * The PIO-C interface for the NetCDF function nc_put_att_ubyte. + */ +int PIOc_put_att_ubyte(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const unsigned char *op) +{ + return PIOc_put_att(ncid, varid, name, xtype, len, op); } /** * @ingroup PIOc_put_att_float * The PIO-C interface for the NetCDF function nc_put_att_float. - * - * This routine is called collectively by all tasks in the communicator - * ios.union_comm. For more information on the underlying NetCDF commmand - * please read about this function in the NetCDF documentation at: - * http://www.unidata.ucar.edu/software/netcdf/docs/group__attributes.html - * - * @param ncid the ncid of the open file, obtained from - * PIOc_openfile() or PIOc_createfile(). - * @param varid the variable ID. - * @return PIO_NOERR for success, error code otherwise. See PIOc_Set_File_Error_Handling */ -int PIOc_put_att_float (int ncid, int varid, const char *name, nc_type xtype, PIO_Offset len, const float *op) +int PIOc_put_att_float(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const float *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - char *errstr; - - errstr = NULL; - ierr = PIO_NOERR; + return PIOc_put_att(ncid, varid, name, xtype, len, op); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_ATT_FLOAT; +/** + * @ingroup PIOc_put_att_ulonglong + * The PIO-C interface for the NetCDF function nc_put_att_ulonglong. + */ +int PIOc_put_att_ulonglong(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const unsigned long long *op) +{ + return PIOc_put_att(ncid, varid, name, xtype, len, op); +} - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); - } +/** + * @ingroup PIOc_put_att_ushort + * The PIO-C interface for the NetCDF function nc_put_att_ushort. + */ +int PIOc_put_att_ushort(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const unsigned short *op) +{ + return PIOc_put_att(ncid, varid, name, xtype, len, op); +} +/** + * @ingroup PIOc_put_att_text + * The PIO-C interface for the NetCDF function nc_put_att_text. + */ +int PIOc_put_att_text(int ncid, int varid, const char *name, + PIO_Offset len, const char *op) +{ + return PIOc_put_att(ncid, varid, name, NC_CHAR, len, op); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_put_att_float(file->fh, varid, name, xtype, (size_t)len, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_att_float(file->fh, varid, name, xtype, (size_t)len, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - ierr = ncmpi_put_att_float(file->fh, varid, name, xtype, len, op);; - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +/** + * @ingroup PIOc_put_att_short + * The PIO-C interface for the NetCDF function nc_put_att_short. + */ +int PIOc_put_att_short(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const short *op) +{ + return PIOc_put_att(ncid, varid, name, xtype, len, op); +} - if(ierr != PIO_NOERR){ - errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char)); - sprintf(errstr,"in file %s",__FILE__); - } - ierr = check_netcdf(file, ierr, errstr,__LINE__); - if(errstr != NULL) free(errstr); - return ierr; +/** + * @ingroup PIOc_put_att_double + * The PIO-C interface for the NetCDF function nc_put_att_double. + */ +int PIOc_put_att_double(int ncid, int varid, const char *name, nc_type xtype, + PIO_Offset len, const double *op) +{ + return PIOc_put_att(ncid, varid, name, xtype, len, op); } + diff --git a/src/clib/pio_put_nc_async.c b/src/clib/pio_put_nc_async.c index c0b621eb903d..ba653397e0bd 100644 --- a/src/clib/pio_put_nc_async.c +++ b/src/clib/pio_put_nc_async.c @@ -1,5073 +1,931 @@ +#include #include #include -/// -/// PIO interface to nc_put_vars_uchar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_uchar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const unsigned char *op) +/** + * Internal PIO function which provides a type-neutral interface to + * nc_put_vars + * + * This routine is called collectively by all tasks in the + * communicator ios.union_comm. + * + * @param ncid identifies the netCDF file + * @param varid the variable ID number + + * @param *start an array of start indicies (must have same number of + * entries as variable has dimensions). If NULL, indices of 0 will be + * used. + * + * @param *count an array of counts (must have same number of entries + * as variable has dimensions). If NULL, counts matching the size of + * the variable will be used. + * + * @param *stride an array of strides (must have same number of + * entries as variable has dimensions). If NULL, strides of 1 will be + * used. + * + * @param xtype the netCDF type of the data being passed in buf. Data + * will be automatically covnerted from this type to the type of the + * variable being written to. + * + * @param buf pointer to the data to be written. + * + * @return PIO_NOERR on success, error code otherwise. + */ +int PIOc_put_vars_tc(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, nc_type xtype, const void *buf) +{ + iosystem_desc_t *ios; /** Pointer to io system information. */ + file_desc_t *file; /** Pointer to file information. */ + int ierr = PIO_NOERR; /** Return code from function calls. */ + int mpierr = MPI_SUCCESS, mpierr2; /** Return code from MPI function codes. */ + int ndims; /** The number of dimensions in the variable. */ + int *dimids; /** The IDs of the dimensions for this variable. */ + PIO_Offset typelen; /** Size (in bytes) of the data type of data in buf. */ + size_t num_elem = 1; /** Number of data elements in the buffer. */ + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + LOG((1, "PIOc_put_vars_tc ncid = %d varid = %d start = %d count = %d " + "stride = %d xtype = %d", ncid, varid, start, count, stride, xtype)); + + /* User must provide some data. */ + if (!buf) + return PIO_EINVAL; + + /* Find the info about this file. */ + if (!(file = pio_get_file_from_id(ncid))) + return PIO_EBADID; + ios = file->iosystem; + + /* Run these on all tasks if async is not in use, but only on + * non-IO tasks if async is in use. */ + if (!ios->async_interface || !ios->ioproc) + { + /* Get the length of the data type. */ + if ((ierr = PIOc_inq_type(ncid, xtype, NULL, &typelen))) + return check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Get the number of dims for this var. */ + if ((ierr = PIOc_inq_varndims(ncid, varid, &ndims))) + return check_netcdf(file, ierr, __FILE__, __LINE__); + + PIO_Offset dimlen[ndims]; + + /* If no count array was passed, we need to know the dimlens + * so we can calculate how many data elements are in the + * buf. */ + if (!count) + { + int dimid[ndims]; + + /* Get the dimids for this var. */ + if ((ierr = PIOc_inq_vardimid(ncid, varid, dimid))) + return check_netcdf(file, ierr, __FILE__, __LINE__); + + /* Get the length of each dimension. */ + for (int vd = 0; vd < ndims; vd++) + if ((ierr = PIOc_inq_dimlen(ncid, dimid[vd], &dimlen[vd]))) + return check_netcdf(file, ierr, __FILE__, __LINE__); + } + + /* Figure out the real start, count, and stride arrays. (The + * user may have passed in NULLs.) */ + PIO_Offset rstart[ndims], rcount[ndims], rstride[ndims]; + for (int vd = 0; vd < ndims; vd++) + { + rstart[vd] = start ? start[vd] : 0; + rcount[vd] = count ? count[vd] : dimlen[vd]; + rstride[vd] = stride ? stride[vd] : 1; + } + + /* How many elements in buf? */ + for (int vd = 0; vd < ndims; vd++) + num_elem *= (rcount[vd] - rstart[vd])/rstride[vd]; + LOG((2, "PIOc_put_vars_tc num_elem = %d", num_elem)); + } + + /* If async is in use, and this is not an IO task, bcast the parameters. */ + if (ios->async_interface) + { + if (!ios->ioproc) + { + int msg = PIO_MSG_PUT_VARS; + char start_present = start ? true : false; + char count_present = count ? true : false; + char stride_present = stride ? true : false; + + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm); + + /* Send the function parameters and associated informaiton + * to the msg handler. */ + if (!mpierr) + mpierr = MPI_Bcast(&ncid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&varid, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&ndims, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&start_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr && start_present) + mpierr = MPI_Bcast((PIO_Offset *)start, ndims, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&count_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr && count_present) + mpierr = MPI_Bcast((PIO_Offset *)count, ndims, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&stride_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm); + if (!mpierr && stride_present) + mpierr = MPI_Bcast((PIO_Offset *)stride, ndims, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&xtype, 1, MPI_INT, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&num_elem, 1, MPI_OFFSET, ios->compmaster, ios->intercomm); + if (!mpierr) + mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, ios->compmaster, ios->intercomm); + LOG((2, "PIOc_put_vars_tc ncid = %d varid = %d ndims = %d start_present = %d " + "count_present = %d stride_present = %d xtype = %d num_elem = %d", ncid, varid, + ndims, start_present, count_present, stride_present, xtype, num_elem)); + + for (int e = 0; e < num_elem; e++) + LOG((2, "PIOc_put_vars_tc element %d = %d", e, ((int *)buf)[e])); + + /* Send the data. */ + if (!mpierr) + mpierr = MPI_Bcast((void *)buf, num_elem * typelen, MPI_BYTE, ios->compmaster, + ios->intercomm); + } + + /* Handle MPI errors. */ + if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr2, __FILE__, __LINE__); + check_mpi(file, mpierr, __FILE__, __LINE__); + + /* /\* Broadcast values currently only known on computation tasks to IO tasks. *\/ */ + /* if ((mpierr = MPI_Bcast(&ndims, 1, MPI_INT, ios->comproot, ios->my_comm))) */ + /* check_mpi(file, mpierr, __FILE__, __LINE__); */ + /* if ((mpierr = MPI_Bcast(&typelen, 1, MPI_OFFSET, ios->comproot, ios->my_comm))) */ + /* check_mpi(file, mpierr, __FILE__, __LINE__); */ + } + + /* If this is an IO task, then call the netCDF function. */ + if (ios->ioproc) + { +#ifdef _PNETCDF + if (file->iotype == PIO_IOTYPE_PNETCDF) + { + vdesc = file->varlist + varid; + if (vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0) + vdesc->request = realloc(vdesc->request, + sizeof(int) * (vdesc->nreqs + PIO_REQUEST_ALLOC_CHUNK)); + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank == 0) + switch(xtype) + { + case NC_BYTE: + ierr = ncmpi_bput_vars_schar(ncid, varid, start, count, stride, buf, request); + break; + case NC_CHAR: + ierr = ncmpi_bput_vars_text(ncid, varid, start, count, stride, buf, request); + break; + case NC_SHORT: + ierr = ncmpi_bput_vars_short(ncid, varid, start, count, stride, buf, request); + break; + case NC_INT: + ierr = ncmpi_bput_vars_int(ncid, varid, start, count, stride, buf, request); + break; + case NC_FLOAT: + ierr = ncmpi_bput_vars_float(ncid, varid, start, count, stride, buf, request); + break; + case NC_DOUBLE: + ierr = ncmpi_bput_vars_double(ncid, varid, start, count, stride, buf, request); + break; + case NC_INT64: + ierr = ncmpi_bput_vars_longlong(ncid, varid, start, count, stride, buf, request); + break; + default: + LOG((0, "Unknown type for pnetcdf file! xtype = %d", xtype)); + + } + else + *request = PIO_REQ_NULL; + + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + } +#endif /* _PNETCDF */ +#ifdef _NETCDF + if (file->iotype != PIO_IOTYPE_PNETCDF && file->do_io) + switch(xtype) + { + case NC_BYTE: + ierr = nc_put_vars_schar(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_CHAR: + ierr = nc_put_vars_schar(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_SHORT: + ierr = nc_put_vars_short(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_INT: + ierr = nc_put_vars_int(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_FLOAT: + ierr = nc_put_vars_float(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_DOUBLE: + ierr = nc_put_vars_double(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; +#ifdef _NETCDF4 + case NC_UBYTE: + ierr = nc_put_vars_uchar(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_USHORT: + ierr = nc_put_vars_ushort(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_UINT: + ierr = nc_put_vars_uint(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_INT64: + ierr = nc_put_vars_longlong(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + case NC_UINT64: + ierr = nc_put_vars_ulonglong(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); + break; + /* case NC_STRING: */ + /* ierr = nc_put_vars_string(ncid, varid, (size_t *)start, (size_t *)count, */ + /* (ptrdiff_t *)stride, (void *)buf); */ + /* break; */ + default: + ierr = nc_put_vars(ncid, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf); +#endif /* _NETCDF4 */ + } +#endif /* _NETCDF */ + } + + /* Broadcast and check the return code. */ + if ((mpierr = MPI_Bcast(&ierr, 1, MPI_INT, ios->ioroot, ios->my_comm))) + return check_mpi(file, mpierr, __FILE__, __LINE__); + if (ierr) + return check_netcdf(file, ierr, __FILE__, __LINE__); + + return ierr; +} + +/** Interface to netCDF data write function. */ +int PIOc_put_vars_text(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const char *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_UCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_uchar(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vars_ushort -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_ushort (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const unsigned short *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_USHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_ushort(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vars_ulonglong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const unsigned long long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_ULONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_ulonglong(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const void *buf, PIO_Offset bufcount, MPI_Datatype buftype) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm(file->fh, varid, start, count, stride, imap, buf, bufcount, buftype, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vars_uint -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_uint (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const unsigned int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_UINT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_uint(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm_uchar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_uchar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const unsigned char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_UCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_uchar(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var_ushort -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_ushort (int ncid, int varid, const unsigned short *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_USHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_ushort(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_ushort(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_ushort(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1_longlong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_longlong (int ncid, int varid, const PIO_Offset index[], const long long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_LONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_longlong(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_longlong(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_longlong(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vara_uchar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_uchar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const unsigned char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_UCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_uchar(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_uchar(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_uchar(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm_short -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_short (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const short *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_SHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_short(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1_long -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_long (int ncid, int varid, const PIO_Offset index[], const long *ip) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_LONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_long(file->fh, varid, (size_t *) index, ip);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_long(file->fh, varid, (size_t *) index, ip);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_long(file->fh, varid, index, ip, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vars_long -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_long (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_LONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_long(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var_short -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_short (int ncid, int varid, const short *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_SHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_short(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_short(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_short(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vara_int -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_INT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_int(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_int(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_int(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1_ushort -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_ushort (int ncid, int varid, const PIO_Offset index[], const unsigned short *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_USHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_ushort(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_ushort(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_ushort(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vara_text -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_text (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_TEXT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_text(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_text(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_text(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm_text -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_text (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_TEXT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_text(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm_ushort -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_ushort (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const unsigned short *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_USHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_ushort(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var_ulonglong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_ulonglong (int ncid, int varid, const unsigned long long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_ULONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_ulonglong(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_ulonglong(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_ulonglong(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var_int -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_int (int ncid, int varid, const int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_INT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_int(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_int(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_int(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var_longlong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_longlong (int ncid, int varid, const long long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_LONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_longlong(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_longlong(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_longlong(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var_schar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_schar (int ncid, int varid, const signed char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_SCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_schar(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_schar(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_schar(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var_uint -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_uint (int ncid, int varid, const unsigned int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_UINT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_uint(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_uint(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_uint(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var (int ncid, int varid, const void *buf, PIO_Offset bufcount, MPI_Datatype buftype) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var(file->fh, varid, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var(file->fh, varid, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var(file->fh, varid, buf, bufcount, buftype, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vara_ushort -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_ushort (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const unsigned short *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_USHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_ushort(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_ushort(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_ushort(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vars_short -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_short (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const short *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_SHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_short(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vara_uint -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_uint (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const unsigned int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_UINT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_uint(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_uint(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_uint(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vara_schar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_schar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const signed char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_SCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_schar(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_schar(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_schar(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm_ulonglong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const unsigned long long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_ULONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_ulonglong(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1_uchar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_uchar (int ncid, int varid, const PIO_Offset index[], const unsigned char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_UCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_uchar(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_uchar(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_uchar(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm_int -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_INT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_int(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vars_schar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_schar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const signed char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_SCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_schar(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1 -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1 (int ncid, int varid, const PIO_Offset index[], const void *buf, PIO_Offset bufcount, MPI_Datatype buftype) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1(file->fh, varid, (size_t *) index, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1(file->fh, varid, (size_t *) index, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1(file->fh, varid, index, buf, bufcount, buftype, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vara_float -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_float (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const float *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_FLOAT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_float(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_float(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_float(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1_float -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_float (int ncid, int varid, const PIO_Offset index[], const float *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_FLOAT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_float(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_float(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_float(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm_float -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_float (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const float *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_FLOAT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_float(file->fh, varid,(size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_float(file->fh, varid,(size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_float(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1_text -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_text (int ncid, int varid, const PIO_Offset index[], const char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_TEXT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_text(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_text(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_text(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vars_text -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_text (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const char *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_TEXT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_text(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm_long -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_long (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_LONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_long(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vars_double -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_double (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const double *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_DOUBLE; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_double(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vara_longlong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const long long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_LONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_longlong(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_longlong(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_longlong(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var_double -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_double (int ncid, int varid, const double *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_DOUBLE; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_double(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_double(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_double(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var_float -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_float (int ncid, int varid, const float *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_FLOAT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_float(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_float(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_float(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1_ulonglong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_ulonglong (int ncid, int varid, const PIO_Offset index[], const unsigned long long *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_ULONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_ulonglong(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_ulonglong(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_ulonglong(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_varm_uint -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_uint (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const unsigned int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_UINT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_uint(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1_uint -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_uint (int ncid, int varid, const PIO_Offset index[], const unsigned int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_UINT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_uint(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_uint(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_uint(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_var1_int -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_int (int ncid, int varid, const PIO_Offset index[], const int *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_INT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_int(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_int(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_int(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; -} - -/// -/// PIO interface to nc_put_vars_float -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_float (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const float *op) -{ - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_FLOAT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_float(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_float(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_float(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_CHAR, op); } -/// -/// PIO interface to nc_put_vara_short -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_short (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const short *op) +/** Interface to netCDF data write function. */ +int PIOc_put_vars_uchar(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, + const unsigned char *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_SHORT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_short(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_short(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_short(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_UBYTE, op); } -/// -/// PIO interface to nc_put_var1_schar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_schar (int ncid, int varid, const PIO_Offset index[], const signed char *op) +/** Interface to netCDF data write function. */ +int PIOc_put_vars_schar(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const signed char *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_SCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_schar(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_schar(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_schar(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_BYTE, op); } -/// -/// PIO interface to nc_put_vara_ulonglong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const unsigned long long *op) +/** Interface to netCDF data write function. */ +int PIOc_put_vars_ushort(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const unsigned short *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_ULONGLONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_ulonglong(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_USHORT, op); } -/// -/// PIO interface to nc_put_varm_double -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_double (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const double *op) +/** Interface to netCDF data write function. */ +int PIOc_put_vars_short(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const PIO_Offset *stride, const short *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_DOUBLE; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_double(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_SHORT, op); } -/// -/// PIO interface to nc_put_vara -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const void *buf, PIO_Offset bufcount, MPI_Datatype buftype) +/** Interface to netCDF data write function. */ +int PIOc_put_vars_uint(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const unsigned int *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara(file->fh, varid, (size_t *) start, (size_t *) count, buf);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara(file->fh, varid, start, count, buf, bufcount, buftype, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_UINT, op); } -/// -/// PIO interface to nc_put_vara_long -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_long (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const long *op) +/** PIO interface to nc_put_vars_int */ +int PIOc_put_vars_int(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const int *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_LONG; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_long(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_long(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_long(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_INT, op); } -/// -/// PIO interface to nc_put_var1_double -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_double (int ncid, int varid, const PIO_Offset index[], const double *op) +/** Interface to netCDF data write function. */ +int PIOc_put_vars_long(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const long *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_DOUBLE; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_double(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_double(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_double(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_INT, op); } -/// -/// PIO interface to nc_put_varm_schar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_schar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const signed char *op) +/** Interface to netCDF data write function. */ +int PIOc_put_vars_float(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const float *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_SCHAR; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_schar(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } - - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - - return ierr; + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_FLOAT, op); } -/// -/// PIO interface to nc_put_var_text -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_text (int ncid, int varid, const char *op) +/** Interface to netCDF data write function. */ +int PIOc_put_vars_longlong(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const long long *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; - - ierr = PIO_NOERR; - - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_TEXT; - - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } - - - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_text(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_text(file->fh, varid, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; - - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; - - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_text(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_INT64, op); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +/** Interface to netCDF data write function. */ +int PIOc_put_vars_double(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const double *op) +{ + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_DOUBLE, op); +} - return ierr; +/** Interface to netCDF data write function. */ +int PIOc_put_vars_ulonglong(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const unsigned long long *op) +{ + return PIOc_put_vars_tc(ncid, varid, start, count, stride, NC_UINT64, op); } -/// -/// PIO interface to nc_put_vars_int -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const int *op) +/** Interface to netCDF data write function. */ +int PIOc_put_var1_tc(int ncid, int varid, const PIO_Offset *index, nc_type xtype, + const void *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; + int ndims; + int ierr; - ierr = PIO_NOERR; + /* Find the number of dimensions. */ + if ((ierr = PIOc_inq_varndims(ncid, varid, &ndims))) + return ierr; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_INT; + /* Set up count array. */ + PIO_Offset count[ndims]; + for (int c = 0; c < ndims; c++) + count[c] = 1; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + return PIOc_put_vars_tc(ncid, varid, index, count, NULL, xtype, op); +} +/** Interface to netCDF data write function. */ +int PIOc_put_var1_text(int ncid, int varid, const PIO_Offset *index, const char *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_CHAR, op); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; +/** Interface to netCDF data write function. */ +int PIOc_put_var1_uchar(int ncid, int varid, const PIO_Offset *index, + const unsigned char *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_UBYTE, op); +} - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; +/** Interface to netCDF data write function. */ +int PIOc_put_var1_schar(int ncid, int varid, const PIO_Offset *index, + const signed char *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_BYTE, op); +} - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_int(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +/** Interface to netCDF data write function. */ +int PIOc_put_var1_ushort(int ncid, int varid, const PIO_Offset *index, + const unsigned short *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_USHORT, op); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +/** Interface to netCDF data write function. */ +int PIOc_put_var1_short(int ncid, int varid, const PIO_Offset *index, + const short *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_SHORT, op); +} - return ierr; +/** Interface to netCDF data write function. */ +int PIOc_put_var1_uint(int ncid, int varid, const PIO_Offset *index, + const unsigned int *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_UINT, op); } -/// -/// PIO interface to nc_put_var1_short -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var1_short (int ncid, int varid, const PIO_Offset index[], const short *op) +/** Interface to netCDF data write function. */ +int PIOc_put_var1_int(int ncid, int varid, const PIO_Offset *index, const int *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; + return PIOc_put_var1_tc(ncid, varid, index, NC_INT, op); +} - ierr = PIO_NOERR; +/** Interface to netCDF data write function. */ +int PIOc_put_var1_float(int ncid, int varid, const PIO_Offset *index, const float *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_FLOAT, op); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR1_SHORT; +/** Interface to netCDF data write function. */ +int PIOc_put_var1_long(int ncid, int varid, const PIO_Offset *index, const long *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_LONG, op); +} - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } +/** Interface to netCDF data write function. */ +int PIOc_put_var1_double(int ncid, int varid, const PIO_Offset *index, + const double *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_DOUBLE, op); +} +/** Interface to netCDF data write function. */ +int PIOc_put_var1_ulonglong(int ncid, int varid, const PIO_Offset *index, + const unsigned long long *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_UINT64, op); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var1_short(file->fh, varid, (size_t *) index, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var1_short(file->fh, varid, (size_t *) index, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; +/** Interface to netCDF data write function. */ +int PIOc_put_var1_longlong(int ncid, int varid, const PIO_Offset *index, + const long long *op) +{ + return PIOc_put_var1_tc(ncid, varid, index, NC_INT64, op); +} - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; +/** Interface to netCDF data write function. */ +int PIOc_put_vara_text(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const char *op) +{ + return PIOc_put_vars_text(ncid, varid, start, count, NULL, op); +} - if(ios->io_rank==0){ - ierr = ncmpi_bput_var1_short(file->fh, varid, index, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +/** Interface to netCDF data write function. */ +int PIOc_put_vara_uchar(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const unsigned char *op) +{ + return PIOc_put_vars_uchar(ncid, varid, start, count, NULL, op); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +/** Interface to netCDF data write function. */ +int PIOc_put_vara_schar(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const signed char *op) +{ + return PIOc_put_vars_schar(ncid, varid, start, count, NULL, op); +} - return ierr; +/** Interface to netCDF data write function. */ +int PIOc_put_vara_ushort(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const unsigned short *op) +{ + return PIOc_put_vars_ushort(ncid, varid, start, count, NULL, op); } -/// -/// PIO interface to nc_put_vars_longlong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const long long *op) +/** Interface to netCDF data write function. */ +int PIOc_put_vara_short(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const short *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; + return PIOc_put_vars_short(ncid, varid, start, count, NULL, op); +} - ierr = PIO_NOERR; +/** Interface to netCDF data write function. */ +int PIOc_put_vara_uint(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const unsigned int *op) +{ + return PIOc_put_vars_uint(ncid, varid, start, count, NULL, op); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS_LONGLONG; +/** Interface to netCDF data write function. */ +int PIOc_put_vara_int(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const int *op) +{ + return PIOc_put_vars_int(ncid, varid, start, count, NULL, op); +} - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } +/** Interface to netCDF data write function. */ +int PIOc_put_vara_long(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const long *op) +{ + return PIOc_put_vars_long(ncid, varid, start, count, NULL, op); +} +/** Interface to netCDF data write function. */ +int PIOc_put_vara_float(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const float *op) +{ + return PIOc_put_vars_float(ncid, varid, start, count, NULL, op); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; +/** Interface to netCDF data write function. */ +int PIOc_put_vara_ulonglong(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const unsigned long long *op) +{ + return PIOc_put_vars_ulonglong(ncid, varid, start, count, NULL, op); +} - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; +/** Interface to netCDF data write function. */ +int PIOc_put_vara_longlong(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const long long *op) +{ + return PIOc_put_vars_longlong(ncid, varid, start, count, NULL, op); +} - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars_longlong(file->fh, varid, start, count, stride, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +/** Interface to netCDF data write function. */ +int PIOc_put_vara_double(int ncid, int varid, const PIO_Offset *start, + const PIO_Offset *count, const double *op) +{ + return PIOc_put_vars_double(ncid, varid, start, count, NULL, op); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +/** Interface to netCDF data write function. */ +int PIOc_put_var_text(int ncid, int varid, const char *op) +{ + return PIOc_put_vars_text(ncid, varid, NULL, NULL, NULL, op); +} - return ierr; +/** Interface to netCDF data write function. */ +int PIOc_put_var_uchar(int ncid, int varid, const unsigned char *op) +{ + return PIOc_put_vars_uchar(ncid, varid, NULL, NULL, NULL, op); } -/// -/// PIO interface to nc_put_vara_double -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vara_double (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const double *op) +/** Interface to netCDF data write function. */ +int PIOc_put_var_schar(int ncid, int varid, const signed char *op) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; + return PIOc_put_vars_schar(ncid, varid, NULL, NULL, NULL, op); +} - ierr = PIO_NOERR; +/** Interface to netCDF data write function. */ +int PIOc_put_var_ushort(int ncid, int varid, const unsigned short *op) +{ + return PIOc_put_vars_tc(ncid, varid, NULL, NULL, NULL, NC_USHORT, op); +} - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARA_DOUBLE; +/** Interface to netCDF data write function. */ +int PIOc_put_var_short(int ncid, int varid, const short *op) +{ + return PIOc_put_vars_short(ncid, varid, NULL, NULL, NULL, op); +} - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } +/** Interface to netCDF data write function. */ +int PIOc_put_var_uint(int ncid, int varid, const unsigned int *op) +{ + return PIOc_put_vars_uint(ncid, varid, NULL, NULL, NULL, op); +} +/** Interface to netCDF data write function. */ +int PIOc_put_var_int(int ncid, int varid, const int *op) +{ + return PIOc_put_vars_int(ncid, varid, NULL, NULL, NULL, op); +} - if(ios->ioproc){ - switch(file->iotype){ -#ifdef _NETCDF -#ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vara_double(file->fh, varid, (size_t *) start, (size_t *) count, op);; - break; - case PIO_IOTYPE_NETCDF4C: -#endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vara_double(file->fh, varid, (size_t *) start, (size_t *) count, op);; - } - break; -#endif -#ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; +/** Interface to netCDF data write function. */ +int PIOc_put_var_long(int ncid, int varid, const long *op) +{ + return PIOc_put_vars_long(ncid, varid, NULL, NULL, NULL, op); +} - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; +/** Interface to netCDF data write function. */ +int PIOc_put_var_float(int ncid, int varid, const float *op) +{ + return PIOc_put_vars_float(ncid, varid, NULL, NULL, NULL, op); +} - if(ios->io_rank==0){ - ierr = ncmpi_bput_vara_double(file->fh, varid, start, count, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; -#endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); - } - } +/** Interface to netCDF data write function. */ +int PIOc_put_var_ulonglong(int ncid, int varid, const unsigned long long *op) +{ + return PIOc_put_vars_ulonglong(ncid, varid, NULL, NULL, NULL, op); +} - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); +/** Interface to netCDF data write function. */ +int PIOc_put_var_longlong(int ncid, int varid, const long long *op) +{ + return PIOc_put_vars_longlong(ncid, varid, NULL, NULL, NULL, op); +} - return ierr; +/** Interface to netCDF data write function. */ +int PIOc_put_var_double(int ncid, int varid, const double *op) +{ + return PIOc_put_vars_double(ncid, varid, NULL, NULL, NULL, op); } -/// -/// PIO interface to nc_put_vars -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_vars (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const void *buf, PIO_Offset bufcount, MPI_Datatype buftype) +/** Interface to netCDF data write function. */ +int PIOc_put_var(int ncid, int varid, const void *buf, PIO_Offset bufcount, + MPI_Datatype buftype) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; - ierr = PIO_NOERR; + ierr = PIO_NOERR; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARS; + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VAR; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + if(ios->async_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + } - if(ios->ioproc){ - switch(file->iotype){ + if(ios->ioproc){ + switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_vars(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - break; - case PIO_IOTYPE_NETCDF4C: + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_var(file->fh, varid, buf);; + break; + case PIO_IOTYPE_NETCDF4C: #endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_vars(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; - } - break; + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_var(file->fh, varid, buf);; + } + break; #endif #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; - if(ios->io_rank==0){ - ierr = ncmpi_bput_vars(file->fh, varid, start, count, stride, buf, bufcount, buftype, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; + if(ios->io_rank==0){ + ierr = ncmpi_bput_var(file->fh, varid, buf, bufcount, buftype, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; #endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } } - } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - return ierr; + return ierr; } -/// -/// PIO interface to nc_put_var_uchar -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_uchar (int ncid, int varid, const unsigned char *op) +/** + * PIO interface to nc_put_vars + * + * This routine is called collectively by all tasks in the + * communicator ios.union_comm. + + * Refer to the + * netcdf documentation. */ +int PIOc_put_vars(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, + const PIO_Offset *stride, const void *buf, PIO_Offset bufcount, + MPI_Datatype buftype) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; - ierr = PIO_NOERR; + ierr = PIO_NOERR; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_UCHAR; + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARS; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + if(ios->async_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + } - if(ios->ioproc){ - switch(file->iotype){ + if(ios->ioproc){ + switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_uchar(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_vars(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, buf);; + break; + case PIO_IOTYPE_NETCDF4C: #endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_uchar(file->fh, varid, op);; - } - break; + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_vars(file->fh, varid, (size_t *)start, (size_t *)count, + (ptrdiff_t *)stride, buf);; + } + break; #endif #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_uchar(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; + if(ios->io_rank==0){ + ierr = ncmpi_bput_vars(file->fh, varid, start, count, stride, buf, + bufcount, buftype, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; #endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } } - } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - return ierr; + return ierr; } -/// -/// PIO interface to nc_put_var_long -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_var_long (int ncid, int varid, const long *op) +/** Interface to netCDF data write function. */ +int PIOc_put_var1(int ncid, int varid, const PIO_Offset *index, const void *buf, + PIO_Offset bufcount, MPI_Datatype buftype) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; - ierr = PIO_NOERR; + ierr = PIO_NOERR; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VAR_LONG; + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VAR1; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + if(ios->async_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + } - if(ios->ioproc){ - switch(file->iotype){ + if(ios->ioproc){ + switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_var_long(file->fh, varid, op);; - break; - case PIO_IOTYPE_NETCDF4C: + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_var1(file->fh, varid, (size_t *) index, buf);; + break; + case PIO_IOTYPE_NETCDF4C: #endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_var_long(file->fh, varid, op);; - } - break; + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_var1(file->fh, varid, (size_t *) index, buf);; + } + break; #endif #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; - if(ios->io_rank==0){ - ierr = ncmpi_bput_var_long(file->fh, varid, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; + if(ios->io_rank==0){ + ierr = ncmpi_bput_var1(file->fh, varid, index, buf, bufcount, buftype, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; #endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } } - } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - return ierr; + return ierr; } -/// -/// PIO interface to nc_put_varm_longlong -/// -/// This routine is called collectively by all tasks in the communicator ios.union_comm. -/// -/// Refer to the netcdf documentation. -/// -int PIOc_put_varm_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const long long *op) +/** Interface to netCDF data write function. */ +int PIOc_put_vara(int ncid, int varid, const PIO_Offset *start, const PIO_Offset *count, const void *buf, + PIO_Offset bufcount, MPI_Datatype buftype) { - int ierr; - int msg; - int mpierr; - iosystem_desc_t *ios; - file_desc_t *file; - var_desc_t *vdesc; - PIO_Offset usage; - int *request; + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; - ierr = PIO_NOERR; + ierr = PIO_NOERR; - file = pio_get_file_from_id(ncid); - if(file == NULL) - return PIO_EBADID; - ios = file->iosystem; - msg = PIO_MSG_PUT_VARM_LONGLONG; + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARA; - if(ios->async_interface && ! ios->ioproc){ - if(ios->compmaster) - mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); - mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); - } + if(ios->async_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, ios->compmaster, ios->intercomm); + } - if(ios->ioproc){ - switch(file->iotype){ + if(ios->ioproc){ + switch(file->iotype){ #ifdef _NETCDF #ifdef _NETCDF4 - case PIO_IOTYPE_NETCDF4P: - ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); - ierr = nc_put_varm_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - break; - case PIO_IOTYPE_NETCDF4C: + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_vara(file->fh, varid, (size_t *) start, (size_t *) count, buf);; + break; + case PIO_IOTYPE_NETCDF4C: #endif - case PIO_IOTYPE_NETCDF: - if(ios->io_rank==0){ - ierr = nc_put_varm_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; - } - break; + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_vara(file->fh, varid, (size_t *) start, (size_t *) count, buf);; + } + break; #endif #ifdef _PNETCDF - case PIO_IOTYPE_PNETCDF: - vdesc = file->varlist + varid; + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; - if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ - vdesc->request = realloc(vdesc->request, - sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); - } - request = vdesc->request+vdesc->nreqs; + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; - if(ios->io_rank==0){ - ierr = ncmpi_bput_varm_longlong(file->fh, varid, start, count, stride, imap, op, request);; - }else{ - *request = PIO_REQ_NULL; - } - vdesc->nreqs++; - flush_output_buffer(file, false, 0); - break; + if(ios->io_rank==0){ + ierr = ncmpi_bput_vara(file->fh, varid, start, count, buf, bufcount, buftype, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; #endif - default: - ierr = iotype_error(file->iotype,__FILE__,__LINE__); + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } } - } - ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); - return ierr; + return ierr; } - diff --git a/src/clib/pio_varm.c b/src/clib/pio_varm.c new file mode 100644 index 000000000000..3110a4333f39 --- /dev/null +++ b/src/clib/pio_varm.c @@ -0,0 +1,1990 @@ +#include +#include +#include + +/// +/// PIO interface to nc_put_varm +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const void *buf, PIO_Offset bufcount, MPI_Datatype buftype) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm(file->fh, varid, start, count, stride, imap, buf, bufcount, buftype, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} + +/// +/// PIO interface to nc_put_varm_uchar +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_uchar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const unsigned char *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_UCHAR; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_uchar(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} + +/// +/// PIO interface to nc_put_varm_short +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_short (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const short *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_SHORT; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_short(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} +/// +/// PIO interface to nc_put_varm_text +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_text (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const char *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_TEXT; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_text(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} + +/// +/// PIO interface to nc_put_varm_ushort +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_ushort (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const unsigned short *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_USHORT; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_ushort(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} + +/// +/// PIO interface to nc_put_varm_ulonglong +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const unsigned long long *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_ULONGLONG; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_ulonglong(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} +/// +/// PIO interface to nc_put_varm_int +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const int *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_INT; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_int(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} + +/// +/// PIO interface to nc_put_varm_float +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_float (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const float *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_FLOAT; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_float(file->fh, varid,(size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_float(file->fh, varid,(size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_float(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} +/// +/// PIO interface to nc_put_varm_long +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_long (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const long *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_LONG; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_long(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} + +/// +/// PIO interface to nc_put_varm_uint +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_uint (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const unsigned int *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_UINT; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_uint(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} + +/// +/// PIO interface to nc_put_varm_double +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_double (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const double *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_DOUBLE; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_double(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} +/// +/// PIO interface to nc_put_varm_schar +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_schar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const signed char *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_SCHAR; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_schar(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} + +/// +/// PIO interface to nc_put_varm_longlong +/// +/// This routine is called collectively by all tasks in the communicator ios.union_comm. +/// +/// Refer to the netcdf documentation. +/// +int PIOc_put_varm_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], const long long *op) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + var_desc_t *vdesc; + PIO_Offset usage; + int *request; + + ierr = PIO_NOERR; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_PUT_VARM_LONGLONG; + + /* Sorry, but varm functions are not supported by the async interface. */ + if(ios->async_interface) + return PIO_EINVAL; + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_var_par_access(file->fh, varid, NC_COLLECTIVE); + ierr = nc_put_varm_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + if(ios->io_rank==0){ + ierr = nc_put_varm_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, op);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: + vdesc = file->varlist + varid; + + if(vdesc->nreqs%PIO_REQUEST_ALLOC_CHUNK == 0 ){ + vdesc->request = realloc(vdesc->request, + sizeof(int)*(vdesc->nreqs+PIO_REQUEST_ALLOC_CHUNK)); + } + request = vdesc->request+vdesc->nreqs; + + if(ios->io_rank==0){ + ierr = ncmpi_bput_varm_longlong(file->fh, varid, start, count, stride, imap, op, request);; + }else{ + *request = PIO_REQ_NULL; + } + vdesc->nreqs++; + flush_output_buffer(file, false, 0); + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + return ierr; +} + +int PIOc_get_varm_uchar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned char *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_UCHAR; + ibuftype = MPI_UNSIGNED_CHAR; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_uchar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_uchar(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_uchar_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_schar (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], signed char *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_SCHAR; + ibuftype = MPI_CHAR; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_schar(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_schar(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_schar_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_double (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], double *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_DOUBLE; + ibuftype = MPI_DOUBLE; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_double(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_double(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_double_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_text (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], char *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_TEXT; + ibuftype = MPI_CHAR; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_text(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_text(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_text_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_int (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], int *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_INT; + ibuftype = MPI_INT; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_int(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_int(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_int_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_uint (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned int *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_UINT; + ibuftype = MPI_UNSIGNED; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_uint(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_uint(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_uint_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], void *buf, PIO_Offset bufcount, MPI_Datatype buftype) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM; + ibufcnt = bufcount; + ibuftype = buftype; + ierr = PIO_NOERR; + + if(ios->async_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm(file->fh, varid, start, count, stride, imap, buf, bufcount, buftype);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_all(file->fh, varid, start, count, stride, imap, buf, bufcount, buftype);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_float (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], float *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_FLOAT; + ibuftype = MPI_FLOAT; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_float(file->fh, varid,(size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_float(file->fh, varid,(size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_float(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_float_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_long (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], long *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_LONG; + ibuftype = MPI_LONG; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_long(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_long(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_long_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_ushort (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned short *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_USHORT; + ibuftype = MPI_UNSIGNED_SHORT; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_ushort(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_ushort(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_ushort_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_longlong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], long long *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_LONGLONG; + ibuftype = MPI_LONG_LONG; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_longlong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_longlong(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_longlong_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_short (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], short *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_SHORT; + ibuftype = MPI_SHORT; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_short(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_short(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_short_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + +int PIOc_get_varm_ulonglong (int ncid, int varid, const PIO_Offset start[], const PIO_Offset count[], const PIO_Offset stride[], const PIO_Offset imap[], unsigned long long *buf) +{ + int ierr; + int msg; + int mpierr; + iosystem_desc_t *ios; + file_desc_t *file; + MPI_Datatype ibuftype; + int ndims; + int ibufcnt; + bool bcast = false; + + file = pio_get_file_from_id(ncid); + if(file == NULL) + return PIO_EBADID; + ios = file->iosystem; + msg = PIO_MSG_GET_VARM_ULONGLONG; + ibuftype = MPI_UNSIGNED_LONG_LONG; + ierr = PIOc_inq_varndims(file->fh, varid, &ndims); + ibufcnt = 1; + for(int i=0;iasync_interface && ! ios->ioproc){ + if(ios->compmaster) + mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm); + mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm); + } + + + if(ios->ioproc){ + switch(file->iotype){ +#ifdef _NETCDF +#ifdef _NETCDF4 + case PIO_IOTYPE_NETCDF4P: + ierr = nc_get_varm_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + break; + case PIO_IOTYPE_NETCDF4C: +#endif + case PIO_IOTYPE_NETCDF: + bcast = true; + if(ios->iomaster){ + ierr = nc_get_varm_ulonglong(file->fh, varid, (size_t *) start, (size_t *) count, (ptrdiff_t *) stride, (ptrdiff_t *) imap, buf);; + } + break; +#endif +#ifdef _PNETCDF + case PIO_IOTYPE_PNETCDF: +#ifdef PNET_READ_AND_BCAST + ncmpi_begin_indep_data(file->fh); + if(ios->iomaster){ + ierr = ncmpi_get_varm_ulonglong(file->fh, varid, start, count, stride, imap, buf);; + }; + ncmpi_end_indep_data(file->fh); + bcast=true; +#else + ierr = ncmpi_get_varm_ulonglong_all(file->fh, varid, start, count, stride, imap, buf);; +#endif + break; +#endif + default: + ierr = iotype_error(file->iotype,__FILE__,__LINE__); + } + } + + ierr = check_netcdf(file, ierr, __FILE__,__LINE__); + + if(ios->async_interface || bcast || + (ios->num_iotasks < ios->num_comptasks)){ + MPI_Bcast(buf, ibufcnt, ibuftype, ios->ioroot, ios->my_comm); + } + + return ierr; +} + diff --git a/src/clib/pioc.c b/src/clib/pioc.c index 22d6ea3307f1..612d99bde7ca 100644 --- a/src/clib/pioc.c +++ b/src/clib/pioc.c @@ -340,7 +340,6 @@ int PIOc_InitDecomp_bc(const int iosysid, const int basetype,const int ndims, co return PIO_NOERR; } - /** ** @ingroup PIO_init ** @brief library initialization used when IO tasks are a subset of compute tasks @@ -351,10 +350,9 @@ int PIOc_InitDecomp_bc(const int iosysid, const int basetype,const int ndims, co ** @param rearr the rearranger to use by default, this may be overriden in the @ref PIO_initdecomp ** @param iosysidp index of the defined system descriptor */ - -int PIOc_Init_Intracomm(const MPI_Comm comp_comm, - const int num_iotasks, const int stride, - const int base,const int rearr, int *iosysidp) +int PIOc_Init_Intracomm(const MPI_Comm comp_comm, const int num_iotasks, + const int stride, const int base, const int rearr, + int *iosysidp) { iosystem_desc_t *iosys; int ierr = PIO_NOERR; @@ -438,10 +436,11 @@ int PIOc_Init_Intracomm(const MPI_Comm comp_comm, &(iosys->iogroup)),__FILE__,__LINE__); /* Create an MPI communicator for the IO tasks. */ - CheckMPIReturn(MPI_Comm_create(iosys->comp_comm, iosys->iogroup, &(iosys->io_comm)),__FILE__,__LINE__); + CheckMPIReturn(MPI_Comm_create(iosys->comp_comm, iosys->iogroup, &(iosys->io_comm)) + ,__FILE__,__LINE__); /* For the tasks that are doing IO, get their rank. */ - if(iosys->ioproc) + if (iosys->ioproc) CheckMPIReturn(MPI_Comm_rank(iosys->io_comm, &(iosys->io_rank)),__FILE__,__LINE__); else iosys->io_rank = -1; diff --git a/src/clib/pioc_support.c b/src/clib/pioc_support.c index 0a5cc4baa461..e08a019c5179 100644 --- a/src/clib/pioc_support.c +++ b/src/clib/pioc_support.c @@ -1,12 +1,84 @@ /** @file * Support functions. */ +#include +#ifdef PIO_ENABLE_LOGGING +#include +#include +#endif /* PIO_ENABLE_LOGGING */ #include #include #include #define versno 2001 +#ifdef PIO_ENABLE_LOGGING +int pio_log_level = 0; +int my_rank; +#endif /* PIO_ENABLE_LOGGING */ + +/** Set the logging level. Set to -1 for nothing, 0 for errors only, 1 + * for important logging, and so on. Log levels below 1 are only + * printed on the io/component root. If the library is not built with + * logging, this function does nothing. */ +int PIOc_set_log_level(int level) +{ +#ifdef PIO_ENABLE_LOGGING + printf("setting log level to %d\n", level); + pio_log_level = level; + MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); + return PIO_NOERR; +#endif /* PIO_ENABLE_LOGGING */ +} + +#ifdef PIO_ENABLE_LOGGING +/** This function prints out a message, if the severity of the message + is lower than the global pio_log_level. To use it, do something + like this: + + pio_log(0, "this computer will explode in %d seconds", i); + + After the first arg (the severity), use the rest like a normal + printf statement. Output will appear on stdout. + This function is heavily based on the function in section 15.5 of + the C FAQ. +*/ +void +pio_log(int severity, const char *fmt, ...) +{ + va_list argp; + int t; + + /* If the severity is greater than the log level, we don't print + this message. */ + if (severity > pio_log_level) + return; + + /* If the severity is 0, only print on rank 0. */ + if (severity < 1 && my_rank != 0) + return; + + /* If the severity is zero, this is an error. Otherwise insert that + many tabs before the message. */ + if (!severity) + fprintf(stdout, "ERROR: "); + for (t = 0; t < severity; t++) + fprintf(stdout, "\t"); + + /* Show the rank. */ + fprintf(stdout, "%d ", my_rank); + + /* Print out the variable list of args with vprintf. */ + va_start(argp, fmt); + vfprintf(stdout, fmt, argp); + va_end(argp); + + /* Put on a final linefeed. */ + fprintf(stdout, "\n"); + fflush(stdout); +} +#endif /* PIO_ENABLE_LOGGING */ + static pio_swapm_defaults swapm_defaults; bool PIO_Save_Decomps=false; /** @@ -114,6 +186,35 @@ void pioassert(_Bool expression, const char *msg, const char *fname, const int l } +/** Handle MPI errors. An error message is sent to stderr, then the + check_netcdf() function is called with PIO_EIO. + + @param file pointer to the file_desc_t info + @param mpierr the MPI return code to handle + @param filename the name of the code file where error occured. + @param line the line of code where error occured. + @return PIO_NOERR for no error, otherwise PIO_EIO. + */ +int check_mpi(file_desc_t *file, const int mpierr, const char *filename, + const int line) +{ + if (mpierr) + { + char errstring[MPI_MAX_ERROR_STRING]; + int errstrlen; + + /* If we can get an error string from MPI, print it to stderr. */ + if (!MPI_Error_string(mpierr, errstring, &errstrlen)) + fprintf(stderr, "MPI ERROR: %s in file %s at line %d\n", + errstring, filename, line); + + /* Handle all MPI errors as PIO_EIO. */ + check_netcdf(file, PIO_EIO, filename, line); + return PIO_EIO; + } + return PIO_NOERR; +} + /** Check the result of a netCDF API call. * * @param file pointer to the PIO structure describing this file. diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 66d8995f7af1..3d26a75f18c3 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -43,6 +43,11 @@ if ("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "GNU") PRIVATE -ffree-line-length-none) endif() +if (PIO_ENABLE_ASYNC) + add_executable (test_intercomm EXCLUDE_FROM_ALL test_intercomm.c) + target_link_libraries (test_intercomm pioc) + add_dependencies (tests test_intercomm) +endif () add_executable (test_names EXCLUDE_FROM_ALL test_names.c) target_link_libraries (test_names pioc) add_executable (test_nc4 EXCLUDE_FROM_ALL test_nc4.c) @@ -62,6 +67,10 @@ add_dependencies (tests pio_unit_test) set (DEFAULT_TEST_TIMEOUT 240) if (PIO_USE_MPISERIAL) + if (PIO_ENABLE_ASYNC) + add_test(NAME test_intercomm + COMMAND test_intercomm) + endif () add_test(NAME test_names COMMAND test_names) add_test(NAME test_nc4 @@ -71,6 +80,12 @@ if (PIO_USE_MPISERIAL) set_tests_properties(pio_unit_test PROPERTIES TIMEOUT ${DEFAULT_TEST_TIMEOUT}) else () + if (PIO_ENABLE_ASYNC) + add_mpi_test(test_intercomm + EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/test_intercomm + NUMPROCS 4 + TIMEOUT ${DEFAULT_TEST_TIMEOUT}) + endif () add_mpi_test(test_names EXECUTABLE ${CMAKE_CURRENT_BINARY_DIR}/test_names NUMPROCS 4 diff --git a/tests/unit/test_intercomm.c b/tests/unit/test_intercomm.c new file mode 100644 index 000000000000..fd999ce91dbc --- /dev/null +++ b/tests/unit/test_intercomm.c @@ -0,0 +1,579 @@ +/** + * @file Tests for PIOc_Intercomm. This tests the Init_Intercomm() + * function, and basic asynch I/O capability. + * + */ +#include +#include +#ifdef TIMING +#include +#endif + +/** The number of possible output netCDF output flavors available to + * the ParallelIO library. */ +#define NUM_NETCDF_FLAVORS 4 + +/** The number of dimensions in the test data. */ +#define NDIM 1 + +/** The length of our test data. */ +#define DIM_LEN 4 + +/** The name of the dimension in the netCDF output file. */ +#define FIRST_DIM_NAME "jojo" +#define DIM_NAME "dim_test_intercomm" + +/** The name of the variable in the netCDF output file. */ +#define FIRST_VAR_NAME "bill" +#define VAR_NAME "var_test_intercomm" + +/** The name of the global attribute in the netCDF output file. */ +#define FIRST_ATT_NAME "willy_gatt_test_intercomm" +#define ATT_NAME "gatt_test_intercomm" +#define SHORT_ATT_NAME "short_gatt_test_intercomm" +#define FLOAT_ATT_NAME "float_gatt_test_intercomm" +#define DOUBLE_ATT_NAME "double_gatt_test_intercomm" + +/** The value of the global attribute in the netCDF output file. */ +#define ATT_VALUE 42 + +/** Error code for when things go wrong. */ +#define ERR_AWFUL 1111 +#define ERR_WRONG 2222 + +/** Handle MPI errors. This should only be used with MPI library + * function calls. */ +#define MPIERR(e) do { \ + MPI_Error_string(e, err_buffer, &resultlen); \ + fprintf(stderr, "MPI error, line %d, file %s: %s\n", __LINE__, __FILE__, err_buffer); \ + MPI_Finalize(); \ + return ERR_AWFUL; \ + } while (0) + +/** Handle non-MPI errors by finalizing the MPI library and exiting + * with an exit code. */ +#define ERR(e) do { \ + fprintf(stderr, "Error %d in %s, line %d\n", e, __FILE__, __LINE__); \ + MPI_Finalize(); \ + return e; \ + } while (0) + +/** Global err buffer for MPI. When there is an MPI error, this buffer + * is used to store the error message that is associated with the MPI + * error. */ +char err_buffer[MPI_MAX_ERROR_STRING]; + +/** This is the length of the most recent MPI error message, stored + * int the global error string. */ +int resultlen; + +/* Check the file for correctness. */ +int +check_file(int iosysid, int format, char *filename, int my_rank, int verbose) +{ + int ncid; + int ret; + int ndims, nvars, ngatts, unlimdimid; + int ndims2, nvars2, ngatts2, unlimdimid2; + int dimid2; + char dimname[NC_MAX_NAME + 1]; + PIO_Offset dimlen; + char dimname2[NC_MAX_NAME + 1]; + PIO_Offset dimlen2; + char varname[NC_MAX_NAME + 1]; + nc_type vartype; + int varndims, vardimids, varnatts; + char varname2[NC_MAX_NAME + 1]; + nc_type vartype2; + int varndims2, vardimids2, varnatts2; + int varid2; + int att_data; + short short_att_data; + float float_att_data; + double double_att_data; + + /* Re-open the file to check it. */ + if (verbose) + printf("%d test_intercomm opening file %s format %d\n", my_rank, filename, format); + if ((ret = PIOc_openfile(iosysid, &ncid, &format, filename, + NC_NOWRITE))) + ERR(ret); + + /* Try to read the data. */ + PIO_Offset start[NDIM] = {0}, count[NDIM] = {DIM_LEN}; + int data_in[DIM_LEN]; + if ((ret = PIOc_get_vars_tc(ncid, 0, start, count, NULL, NC_INT, data_in))) + ERR(ret); + for (int i = 0; i < DIM_LEN; i++) + { + if (verbose) + printf("%d test_intercomm read data_in[%d] = %d\n", my_rank, i, data_in[i]); + if (data_in[i] != i) + ERR(ERR_AWFUL); + } + + /* Find the number of dimensions, variables, and global attributes.*/ + if ((ret = PIOc_inq(ncid, &ndims, &nvars, &ngatts, &unlimdimid))) + ERR(ret); + if (ndims != 1 || nvars != 1 || ngatts != 4 || unlimdimid != -1) + ERR(ERR_WRONG); + + /* This should return PIO_NOERR. */ + if ((ret = PIOc_inq(ncid, NULL, NULL, NULL, NULL))) + ERR(ret); + + /* Check the other functions that get these values. */ + if ((ret = PIOc_inq_ndims(ncid, &ndims2))) + ERR(ret); + if (ndims2 != 1) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_nvars(ncid, &nvars2))) + ERR(ret); + if (nvars2 != 1) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_natts(ncid, &ngatts2))) + ERR(ret); + if (ngatts2 != 4) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_unlimdim(ncid, &unlimdimid2))) + ERR(ret); + if (unlimdimid != -1) + ERR(ERR_WRONG); + + /* Check out the dimension. */ + if ((ret = PIOc_inq_dim(ncid, 0, dimname, &dimlen))) + ERR(ret); + if (strcmp(dimname, DIM_NAME) || dimlen != DIM_LEN) + ERR(ERR_WRONG); + + /* Check the other functions that get these values. */ + if ((ret = PIOc_inq_dimname(ncid, 0, dimname2))) + ERR(ret); + if (strcmp(dimname2, DIM_NAME)) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_dimlen(ncid, 0, &dimlen2))) + ERR(ret); + if (dimlen2 != DIM_LEN) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_dimid(ncid, DIM_NAME, &dimid2))) + ERR(ret); + if (dimid2 != 0) + ERR(ERR_WRONG); + + /* Check out the variable. */ + if ((ret = PIOc_inq_var(ncid, 0, varname, &vartype, &varndims, &vardimids, &varnatts))) + ERR(ret); + if (strcmp(varname, VAR_NAME) || vartype != NC_INT || varndims != NDIM || + vardimids != 0 || varnatts != 0) + ERR(ERR_WRONG); + + /* Check the other functions that get these values. */ + if ((ret = PIOc_inq_varname(ncid, 0, varname2))) + ERR(ret); + if (strcmp(varname2, VAR_NAME)) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_vartype(ncid, 0, &vartype2))) + ERR(ret); + if (vartype2 != NC_INT) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_varndims(ncid, 0, &varndims2))) + ERR(ret); + if (varndims2 != NDIM) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_vardimid(ncid, 0, &vardimids2))) + ERR(ret); + if (vardimids2 != 0) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_varnatts(ncid, 0, &varnatts2))) + ERR(ret); + if (varnatts2 != 0) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_varid(ncid, VAR_NAME, &varid2))) + ERR(ret); + if (varid2 != 0) + ERR(ERR_WRONG); + + /* Check out the global attributes. */ + nc_type atttype; + PIO_Offset attlen; + char myattname[NC_MAX_NAME + 1]; + int myid; + if ((ret = PIOc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &atttype, &attlen))) + ERR(ret); + if (atttype != NC_INT || attlen != 1) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_attlen(ncid, NC_GLOBAL, ATT_NAME, &attlen))) + ERR(ret); + if (attlen != 1) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_attname(ncid, NC_GLOBAL, 0, myattname))) + ERR(ret); + if (strcmp(ATT_NAME, myattname)) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_attid(ncid, NC_GLOBAL, ATT_NAME, &myid))) + ERR(ret); + if (myid != 0) + ERR(ERR_WRONG); + if ((ret = PIOc_get_att_int(ncid, NC_GLOBAL, ATT_NAME, &att_data))) + ERR(ret); + if (verbose) + printf("%d test_intercomm att_data = %d\n", my_rank, att_data); + if (att_data != ATT_VALUE) + ERR(ERR_WRONG); + if ((ret = PIOc_inq_att(ncid, NC_GLOBAL, SHORT_ATT_NAME, &atttype, &attlen))) + ERR(ret); + if (atttype != NC_SHORT || attlen != 1) + ERR(ERR_WRONG); + if ((ret = PIOc_get_att_short(ncid, NC_GLOBAL, SHORT_ATT_NAME, &short_att_data))) + ERR(ret); + if (short_att_data != ATT_VALUE) + ERR(ERR_WRONG); + if ((ret = PIOc_get_att_float(ncid, NC_GLOBAL, FLOAT_ATT_NAME, &float_att_data))) + ERR(ret); + if (float_att_data != ATT_VALUE) + ERR(ERR_WRONG); + if ((ret = PIOc_get_att_double(ncid, NC_GLOBAL, DOUBLE_ATT_NAME, &double_att_data))) + ERR(ret); + if (double_att_data != ATT_VALUE) + ERR(ERR_WRONG); + + + /* Close the file. */ + if (verbose) + printf("%d test_intercomm closing file (again) ncid = %d\n", my_rank, ncid); + if ((ret = PIOc_closefile(ncid))) + ERR(ret); + + return 0; +} + +/** Run Tests for Init_Intercomm + * + * @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; + + /** 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_intercomm_pnetcdf.nc", + "test_intercomm_classic.nc", + "test_intercomm_serial4.nc", + "test_intercomm_parallel4.nc"}; + + /** The ID for the parallel I/O system. */ + int iosysid; + + /** The ncid of the netCDF file. */ + int ncid; + + /** The ID of the netCDF varable. */ + int varid; + + /** 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, "test_intercomm Number of processors must be exactly 4!\n"); + if (verbose) + printf("%d: test_intercomm ParallelIO Library test_intercomm running on %d processors.\n", + my_rank, ntasks); + + /* For example, if I have 4 processors, and I want to have 2 of them be computational, */ + /* and 2 of them be IO: component count is 1 */ + /* peer_comm = MPI_COMM_WORLD */ + /* comp_comms is an array of comms of size 1 with a comm defined just over tasks (0,1) */ + /* io_comm is a comm over tasks (2,3) */ + + /* Initialize the PIO IO system. This specifies how many and which + * processors are involved in I/O. */ +#define COMPONENT_COUNT 1 + MPI_Comm comp_comms; + MPI_Comm io_comm; + MPI_Group io_group; + MPI_Group comp_group; + + /* Tasks 0 and 1 will be computational. Tasks 2 and 3 will be I/O + * tasks. */ + + // Get the group of processes in MPI_COMM_WORLD + MPI_Group world_group; + MPI_Comm_group(MPI_COMM_WORLD, &world_group); + int comp_task; + + if (my_rank == 0 || my_rank == 1) + { + /* We will define comp_comm. The io_comm will get null. */ + io_comm = MPI_COMM_NULL; + int n = 2; + const int ranks[2] = {0, 1}; + + /* Construct a group with ranks 0, 1 in world_group. */ + MPI_Group_incl(world_group, n, ranks, &comp_group); + MPI_Comm_create_group(MPI_COMM_WORLD, comp_group, 0, &comp_comms); + if (verbose) + printf("%d test_intercomm included in comp_group.\n", my_rank); + + comp_task = 1; + } + else + { + /* We will define io_comm. The comp_comms array will get nulls. */ + comp_comms = MPI_COMM_NULL; + int n = 2; + const int ranks[2] = {2, 3}; + + /* Construct a group with ranks 2, 3 in world_group. */ + MPI_Group_incl(world_group, n, ranks, &io_group); + MPI_Comm_create_group(MPI_COMM_WORLD, io_group, 0, &io_comm); + if (verbose) + printf("%d test_intercomm included in io_group.\n", my_rank); + + comp_task = 0; + } + + /* Turn on logging. */ + if ((ret = PIOc_set_log_level(2))) + ERR(ret); + + /* Initialize the async setup. */ + if ((ret = PIOc_Init_Intercomm(COMPONENT_COUNT, MPI_COMM_WORLD, &comp_comms, + io_comm, &iosysid))) + ERR(ret); + if (verbose) + printf("%d test_intercomm init intercomm returned %d iosysid = %d\n", my_rank, ret, + iosysid); + + /* 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_NETCDF_FLAVORS; fmt++) +/* for (int fmt = 1; fmt < 2; fmt++) */ + { + int ncid, varid, dimid; + PIO_Offset start[NDIM], count[NDIM] = {0}; + int data[DIM_LEN]; + + /* Create a netCDF file with one dimension and one variable. */ + if (verbose) + printf("%d test_intercomm creating file %s\n", my_rank, filename[fmt]); + if ((ret = PIOc_createfile(iosysid, &ncid, &format[fmt], filename[fmt], + NC_CLOBBER))) + ERR(ret); + if (verbose) + printf("%d test_intercomm file created ncid = %d\n", my_rank, ncid); + + /* /\* End define mode, then re-enter it. *\/ */ + if ((ret = PIOc_enddef(ncid))) + ERR(ret); + if (verbose) + printf("%d test_intercomm calling redef\n", my_rank); + if ((ret = PIOc_redef(ncid))) + ERR(ret); + + /* Test the inq_format function. */ + int myformat; + if ((ret = PIOc_inq_format(ncid, &myformat))) + ERR(ret); + if ((format[fmt] == PIO_IOTYPE_PNETCDF || format[fmt] == PIO_IOTYPE_NETCDF) && + myformat != 1) + ERR(ERR_AWFUL); + else if ((format[fmt] == PIO_IOTYPE_NETCDF4C || format[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; + #define NUM_TYPES 11 + 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 = format[fmt] == PIO_IOTYPE_NETCDF ? NC_DOUBLE : NC_UINT64; + 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 (verbose) + printf("%d test_intercomm defining dimension %s\n", my_rank, DIM_NAME); + 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); + + /* Define a 1-D variable. */ + char varname2[NC_MAX_NAME + 1]; + if (verbose) + printf("%d test_intercomm defining variable %s\n", my_rank, VAR_NAME); + 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); + + /* Add a global attribute. */ + if (verbose) + printf("%d test_intercomm writing attributes %s\n", my_rank, ATT_NAME); + 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); + + /* Write an att and delete it. */ + nc_type myatttype; + 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); + + /* End define mode. */ + if (verbose) + printf("%d test_intercomm ending define mode ncid = %d\n", my_rank, ncid); + 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; + if (verbose) + printf("%d test_intercomm writing data\n", my_rank); + if (verbose) + printf("%d test_intercomm writing data\n", my_rank); + 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 (verbose) + printf("%d test_intercomm closing file ncid = %d\n", my_rank, ncid); + if ((ret = PIOc_closefile(ncid))) + ERR(ret); + + /* Check the file for correctness. */ + if ((ret = check_file(iosysid, format[fmt], filename[fmt], my_rank, verbose))) + ERR(ret); + + /* Now delete the file. */ + /* if ((ret = PIOc_deletefile(iosysid, filename[fmt]))) */ + /* ERR(ret); */ + /* if ((ret = PIOc_openfile(iosysid, &ncid, &format[fmt], filename[fmt], */ + /* NC_NOWRITE)) != PIO_ENFILE) */ + /* ERR(ERR_AWFUL); */ + + } /* next netcdf format flavor */ + } + + /* Free local MPI resources. */ + if (verbose) + printf("%d test_intercomm Freeing local MPI resources...\n", my_rank); + MPI_Group_free(&world_group); + if (comp_task) + { + MPI_Group_free(&comp_group); + MPI_Comm_free(&comp_comms); + } + else + { + MPI_Group_free(&io_group); + MPI_Comm_free(&io_comm); + } + + /* Finalize the IO system. */ + if (verbose) + printf("%d test_intercomm 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 + + if (verbose) + printf("%d test_intercomm SUCCESS!!\n", my_rank); + + + return 0; +}