13 #ifdef HAVE_SYS_RESOURCE_H
14 #include <sys/resource.h>
16 #ifdef HAVE_SYS_TYPES_H
17 #include <sys/types.h>
19 #ifdef HAVE_SYS_STAT_H
25 #include "ncdispatch.h"
38 static int nc_initialized = 0;
81 nc_local_initialize(
void)
92 NC_check_file_type(
const char *path,
int use_parallel,
void *mpi_info,
93 enum FileType* filetype,
int* version)
95 char magic[MAGIC_NUMBER_LEN];
97 *filetype = FT_UNKNOWN;
107 MPI_Comm comm = MPI_COMM_WORLD;
108 MPI_Info info = MPI_INFO_NULL;
110 if(mpi_info != NULL) {
111 comm = ((NC_MPI_INFO*)mpi_info)->comm;
112 info = ((NC_MPI_INFO*)mpi_info)->info;
114 if((retval = MPI_File_open(comm, (
char *)path, MPI_MODE_RDONLY,info,
115 &fh)) != MPI_SUCCESS)
117 if((retval = MPI_File_read(fh, magic, MAGIC_NUMBER_LEN, MPI_CHAR,
118 &status)) != MPI_SUCCESS)
120 if((retval = MPI_File_close(&fh)) != MPI_SUCCESS)
127 #ifdef HAVE_SYS_STAT_H
131 if(path == NULL || strlen(path)==0)
134 if (!(fp = fopen(path,
"r")))
137 #ifdef HAVE_SYS_STAT_H
141 if(!(fstat(fileno(fp),&st) == 0)) {
146 if(st.st_size < MAGIC_NUMBER_LEN) {
153 i = fread(magic, MAGIC_NUMBER_LEN, 1, fp);
163 if(magic[1] ==
'H' && magic[2] ==
'D' && magic[3] ==
'F') {
166 }
else if(magic[0] ==
'\016' && magic[1] ==
'\003'
167 && magic[2] ==
'\023' && magic[3] ==
'\001') {
170 }
else if(magic[0] ==
'C' && magic[1] ==
'D' && magic[2] ==
'F') {
172 if(magic[3] ==
'\001')
174 else if(magic[3] ==
'\002')
176 else if(magic[3] ==
'\005') {
177 *filetype = FT_PNETCDF;
451 size_t *chunksizehintp,
int *ncidp)
453 return NC_create(path, cmode, initialsz, 0,
454 chunksizehintp, 0, NULL, ncidp);
466 nc__create_mp(
const char *path,
int cmode,
size_t initialsz,
467 int basepe,
size_t *chunksizehintp,
int *ncidp)
469 return NC_create(path, cmode, initialsz, basepe,
470 chunksizehintp, 0, NULL, ncidp);
588 nc_open(
const char *path,
int mode,
int *ncidp)
590 return NC_open(path, mode, 0, NULL, 0, NULL, ncidp);
646 size_t *chunksizehintp,
int *ncidp)
648 return NC_open(path, mode, 0, chunksizehintp, 0,
661 nc__open_mp(
const char *path,
int mode,
int basepe,
662 size_t *chunksizehintp,
int *ncidp)
664 return NC_open(path, mode, basepe, chunksizehintp,
690 if ((stat = NC_check_id(ncid, &ncp)))
692 if(ncp->path == NULL) {
693 if(pathlen) *pathlen = 0;
694 if(path) path[0] =
'\0';
696 if (pathlen) *pathlen = strlen(ncp->path);
697 if (path) strcpy(path, ncp->path);
754 int stat = NC_check_id(ncid, &ncp);
756 return ncp->dispatch->redef(ncid);
819 status = NC_check_id(ncid, &ncp);
820 if(status !=
NC_NOERR)
return status;
821 return ncp->dispatch->_enddef(ncid,0,1,0,1);
906 nc__enddef(
int ncid,
size_t h_minfree,
size_t v_align,
size_t v_minfree,
910 int stat = NC_check_id(ncid, &ncp);
912 return ncp->dispatch->_enddef(ncid,h_minfree,v_align,v_minfree,r_align);
986 int stat = NC_check_id(ncid, &ncp);
988 return ncp->dispatch->sync(ncid);
1037 int stat = NC_check_id(ncid, &ncp);
1046 stat = ncp->dispatch->abort(ncid);
1047 del_from_NCList(ncp);
1096 int stat = NC_check_id(ncid, &ncp);
1101 if(ncp->refcount <= 0)
1104 stat = ncp->dispatch->close(ncid);
1106 del_from_NCList(ncp);
1214 int stat = NC_check_id(ncid, &ncp);
1216 return ncp->dispatch->set_fill(ncid,fillmode,old_modep);
1231 nc_inq_base_pe(
int ncid,
int *pe)
1234 int stat = NC_check_id(ncid, &ncp);
1236 return ncp->dispatch->inq_base_pe(ncid,pe);
1251 nc_set_base_pe(
int ncid,
int pe)
1254 int stat = NC_check_id(ncid, &ncp);
1256 return ncp->dispatch->set_base_pe(ncid,pe);
1281 int stat = NC_check_id(ncid, &ncp);
1283 return ncp->dispatch->inq_format(ncid,formatp);
1315 int stat = NC_check_id(ncid, &ncp);
1317 return ncp->dispatch->inq_format_extended(ncid,formatp,modep);
1365 nc_inq(
int ncid,
int *ndimsp,
int *nvarsp,
int *nattsp,
int *unlimdimidp)
1368 int stat = NC_check_id(ncid, &ncp);
1370 return ncp->dispatch->inq(ncid,ndimsp,nvarsp,nattsp,unlimdimidp);
1374 nc_inq_nvars(
int ncid,
int *nvarsp)
1377 int stat = NC_check_id(ncid, &ncp);
1379 return ncp->dispatch->inq(ncid, NULL, nvarsp, NULL, NULL);
1453 if(xtype <= ATOMICTYPEMAX) {
1455 if(name) strncpy(name,NC_atomictypename(xtype),
NC_MAX_NAME);
1456 if(size) *size = NC_atomictypelen(xtype);
1459 int stat = NC_check_id(ncid, &ncp);
1461 return ncp->dispatch->inq_type(ncid,xtype,name,size);
1501 NC_create(
const char *path,
int cmode,
size_t initialsz,
1502 int basepe,
size_t *chunksizehintp,
int useparallel,
1503 void* mpi_info,
int *ncidp)
1507 NC_Dispatch* dispatcher = NULL;
1518 if ((stat = NC_initialize()))
1521 nc_local_initialize();
1527 ncp = find_in_NCList_by_name(path);
1532 if((isurl = NC_testurl(path)))
1533 model = NC_urlmodel(path);
1538 model = NC_DISPATCH_NC4;
1540 model = NC_DISPATCH_NC5;
1542 model = NC_DISPATCH_NC3;
1547 int format = nc_get_default_format();
1552 model = NC_DISPATCH_NC4;
1556 model = NC_DISPATCH_NC4;
1564 model = NC_DISPATCH_NC3;
1577 if (!(dispatcher = NC_get_dispatch_override()))
1582 #ifdef USE_CDMREMOTE
1583 if(model == (NC_DISPATCH_NC4 | NC_DISPATCH_NCR))
1584 dispatcher = NCCR_dispatch_table;
1587 if(model == (NC_DISPATCH_NC4))
1588 dispatcher = NC4_dispatch_table;
1592 if(model == (NC_DISPATCH_NC3 | NC_DISPATCH_NCD))
1593 dispatcher = NCD2_dispatch_table;
1597 if(model == (NC_DISPATCH_NC5))
1598 dispatcher = NC5_dispatch_table;
1601 if(model == (NC_DISPATCH_NC3))
1602 dispatcher = NC3_dispatch_table;
1608 stat = new_NC(dispatcher,path,cmode,&ncp);
1609 if(stat)
return stat;
1620 if ((stat = dispatcher->create(path, cmode, initialsz, basepe, chunksizehintp,
1621 useparallel, mpi_info, dispatcher, ncp))) {
1622 del_from_NCList(ncp);
1625 if(ncidp)*ncidp = ncp->ext_ncid;
1646 NC_open(
const char *path,
int cmode,
1647 int basepe,
size_t *chunksizehintp,
1648 int useparallel,
void* mpi_info,
1653 NC_Dispatch* dispatcher = NULL;
1658 enum FileType filetype = FT_UNKNOWN;
1660 if(!nc_initialized) {
1661 stat = NC_initialize();
1662 if(stat)
return stat;
1664 nc_local_initialize();
1670 ncp = find_in_NCList_by_name(path);
1673 if(ncidp) *ncidp = ncp->ext_ncid;
1678 isurl = NC_testurl(path);
1680 model = NC_urlmodel(path);
1682 filetype = FT_UNKNOWN;
1686 stat = NC_check_file_type(path,useparallel,mpi_info,
1687 &filetype,&version);
1691 if(version == 1 || version == 2)
1692 model = NC_DISPATCH_NC3;
1695 model = NC_DISPATCH_NC4;
1698 model = NC_DISPATCH_NC5;
1709 if(cmode & NC_PNETCDF) model |= NC_DISPATCH_NC5;
1710 else if(cmode & NC_NETCDF4) model |= NC_DISPATCH_NC4;
1713 if(model == 0) model = NC_DISPATCH_NC3;
1716 if(model & NC_DISPATCH_NC4)
1718 else if(model & NC_DISPATCH_NC3) {
1719 cmode &= ~NC_NETCDF4;
1721 }
else if(model & NC_DISPATCH_NC5) {
1726 if((cmode &
NC_MPIIO && cmode & NC_MPIPOSIX))
1730 dispatcher = NC_get_dispatch_override();
1731 if(dispatcher != NULL)
goto havetable;
1734 #if defined(USE_CDMREMOTE)
1735 if(model == (NC_DISPATCH_NC4 | NC_DISPATCH_NCR))
1736 dispatcher = NCCR_dispatch_table;
1739 #if defined(USE_DAP)
1740 if(model == (NC_DISPATCH_NC3 | NC_DISPATCH_NCD))
1741 dispatcher = NCD2_dispatch_table;
1744 #if defined(USE_PNETCDF)
1745 if(model == (NC_DISPATCH_NC5))
1746 dispatcher = NC5_dispatch_table;
1749 #if defined(USE_NETCDF4)
1750 if(model == (NC_DISPATCH_NC4))
1751 dispatcher = NC4_dispatch_table;
1754 if(model == (NC_DISPATCH_NC3))
1755 dispatcher = NC3_dispatch_table;
1762 stat = new_NC(dispatcher,path,cmode,&ncp);
1763 if(stat)
return stat;
1774 stat = dispatcher->open(path, cmode, basepe, chunksizehintp,
1775 useparallel, mpi_info, dispatcher, ncp);
1777 if(ncidp) *ncidp = ncp->ext_ncid;
1779 del_from_NCList(ncp);
1790 static int pseudofd = 0;
1800 #ifdef HAVE_GETRLIMIT
1802 if(getrlimit(RLIMIT_NOFILE,&rl) == 0) {
1803 if(rl.rlim_max != RLIM_INFINITY)
1804 maxfd = (int)rl.rlim_max;
1805 if(rl.rlim_cur != RLIM_INFINITY)
1806 maxfd = (int)rl.rlim_cur;
#define NC_PNETCDF
Use parallel-netcdf library.
int nc__open(const char *path, int mode, size_t *chunksizehintp, int *ncidp)
Open a netCDF file with extra performance parameters for the classic library.
#define NC_ENFILE
Too many netcdfs open.
#define NC_CLASSIC_MODEL
Enforce classic model.
#define NC_MAX_VAR_DIMS
max per variable dimensions
int nc_redef(int ncid)
Put open netcdf dataset into define mode.
int nc__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, size_t r_align)
Leave define mode with performance tuning.
#define NC_MPIIO
Turn on MPI I/O.
int nc_inq_format(int ncid, int *formatp)
Inquire about the binary format of a netCDF file as presented by the API.
int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
int nc_type
The nc_type type is just an int.
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
int nc_inq_format_extended(int ncid, int *formatp, int *modep)
Obtain more detailed (vis-a-vis nc_inq_format) format information about an open dataset.
#define NC_ENOTNC
Not a netcdf file.
int nc_close(int ncid)
Close an open netCDF dataset.
#define NC_FORMAT_64BIT
Format specifier for nc_set_default_format() and returned by nc_inq_format.
#define NC_EBADTYPE
Not a netcdf data type.
#define NC_SIZEHINT_DEFAULT
Let nc__create() or nc__open() figure out a suitable buffer size.
#define NC_EINVAL
Invalid Argument.
int nc_set_fill(int ncid, int fillmode, int *old_modep)
Change the fill-value mode to improve write performance.
#define NC_MAX_NAME
Maximum for classic library.
#define NC_NAT
Not A Type.
int nc_inq_type(int ncid, nc_type xtype, char *name, size_t *size)
Inquire about a type.
#define NC_EPARINIT
Error initializing for parallel access.
#define NC_NETCDF4
Use netCDF-4/HDF5 format.
int nc__create(const char *path, int cmode, size_t initialsz, size_t *chunksizehintp, int *ncidp)
Create a netCDF file with some extra parameters controlling classic file cacheing.
#define NC_FORMAT_NETCDF4_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
#define NC_FORMAT_NETCDF4
Format specifier for nc_set_default_format() and returned by nc_inq_format.
int nc_inq_path(int ncid, size_t *pathlen, char *path)
Get the file pathname (or the opendap URL) which was used to open/create the ncid's file...
#define NC_NOERR
No Error.
int nc_open(const char *path, int mode, int *ncidp)
Open an existing netCDF file.
int nc_enddef(int ncid)
Leave define mode.
#define NC_FORMAT_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
int nc_sync(int ncid)
Synchronize an open netcdf dataset to disk.
int nc_create(const char *path, int cmode, int *ncidp)
Create a new netCDF file.
#define NC_MPIPOSIX
Turn on MPI POSIX I/O.