1 /*
2  *  Copyright (C) 2003, Northwestern University and Argonne National Laboratory
3  *  See COPYRIGHT notice in top-level directory.
4  */
5 /* $Id: nc.h 2723 2016-12-18 06:21:12Z wkliao $ */
6 #ifndef _NC_H_
7 #define _NC_H_
8 
9 /*
10  * netcdf library 'private' data structures, objects and interfaces
11  */
12 
13 #include <stddef.h>     /* size_t */
14 #include <sys/types.h>  /* off_t */
15 
16 #include "ncio.h"       /* ncio */
17 #include "fbits.h"
18 
19 /* for put request less than 4KB, copy it to a buffer and do byte swap there,
20  * so if the user buffer is immutable (assuming smaller than 4KB), it will not
21  * cause seg fault. Not a perfect solution, but should be sufficient for most
22  * of the cases.
23  */
24 #define NC_BYTE_SWAP_BUFFER_SIZE 4096
25 
26 /* define MPI_OFFSET if not defined */
27 #ifndef HAVE_MPI_OFFSET_DATATYPE
28     #ifdef HAVE_MPI_LONG_LONG_INT
29         #define MPI_OFFSET MPI_LONG_LONG_INT
30     #else
31         #define MPI_OFFSET MPI_INT
32     #endif
33 #endif
34 
35 enum API_KIND {
36     API_VARD, /* do not check start and count, no flexible APIs */
37     API_VARN, /* do not check start and count */
38     API_VAR,  /* do not check start and count */
39     API_VAR1, /* check start */
40     API_VARA, /* check start and count */
41     API_VARS, /* check start and count */
42     API_VARM  /* check start and count */
43 };
44 
45 #define WRITE_REQ 0
46 #define READ_REQ  1
47 
48 #define INDEP_IO 0
49 #define COLL_IO  1
50 #define NONBLOCKING_IO  -1
51 
52 /* C macros for TRACE MPI calls */
53 #ifdef PNETCDF_TRACE_MPI_COMM
54 #define TRACE_COMM(x) printf("TRACE-MPI-COMM: FILE %s FUNC %s() LINE %d calling %s()\n",__FILE__,__func__,__LINE__,#x),mpireturn=x
55 #else
56 #define TRACE_COMM(x) mpireturn=x
57 #endif
58 
59 #ifdef PNETCDF_TRACE_MPI_IO
60 #define TRACE_IO(x) printf("TRACE-MPI-IO:   FILE %s FUNC %s() LINE %d calling %s()\n",__FILE__,__func__,__LINE__,#x),mpireturn=x
61 #else
62 #define TRACE_IO(x) mpireturn=x
63 #endif
64 
65 
66 /* XXX: this seems really low.  do we end up spending a ton of time mallocing?
67  * could we reduce that by increasing this to something 21st century? */
68 #ifndef NC_ARRAY_GROWBY
69 #define NC_ARRAY_GROWBY 4
70 #endif
71 
72 /* ncmpi_create/ncmpi_open set up header to be 'chunksize' big and to grow
73  * by 'chunksize' as new items added. This used to be 4k. 256k lets us read
74  * in an entire climate header in one go */
75 #define NC_DEFAULT_CHUNKSIZE 262144
76 
77 /* when variable's nctype is NC_CHAR, I/O buffer's MPI type must be MPI_CHAR
78  * and vice versa */
79 #define NCMPII_ECHAR(nctype, mpitype) ((((nctype) == NC_CHAR) == ((mpitype) != MPI_CHAR)) ? NC_ECHAR : NC_NOERR)
80 
81 /*
82  * The extern size of an empty
83  * netcdf version 1 file.
84  * The initial value of ncp->xsz.
85  */
86 #define MIN_NC_XSZ 32
87 
88 /* netcdf file format:
89      netcdf_file  = header  data
90      header       = magic  numrecs  dim_list  gatt_list  var_list
91      magic        = 'C'  'D'  'F'  VERSION
92      VERSION      = \x01 | \x02 | \x05
93      numrecs      = NON_NEG | STREAMING
94      dim_list     = ABSENT | NC_DIMENSION  nelems  [dim ...]
95      gatt_list    = att_list
96      att_list     = ABSENT | NC_ATTRIBUTE  nelems  [attr ...]
97      var_list     = ABSENT | NC_VARIABLE   nelems  [var ...]
98      ABSENT       = ZERO  ZERO                  // Means list is not present
99      ZERO         = \x00 \x00 \x00 \x00         // 32-bit zero
100 
101   Minimum happens when nothing is defined, i.e.
102      magic              -- 4 bytes
103      numrecs            -- 4 bytes for CDF-1 and CDF-2, 8 bytes for CDF-5
104      dim_list = ABSENT  -- 8 bytes
105      gatt_list = ABSENT -- 8 bytes
106      var_list = ABSENT  -- 8 bytes
107 */
108 
109 typedef struct NC NC; /* forward reference */
110 
111 /*
112  *  The internal data types
113  */
114 typedef enum {
115     NC_UNSPECIFIED =  0,
116 /*  NC_BITFIELD    =  7, */
117 /*  NC_STRING      =  8, */
118     NC_DIMENSION   = 10,  /* \x00 \x00 \x00 \x0A */
119     NC_VARIABLE    = 11,  /* \x00 \x00 \x00 \x0B */
120     NC_ATTRIBUTE   = 12   /* \x00 \x00 \x00 \x0C */
121 } NCtype;
122 
123 
124 /*
125  * Counted string for names and such
126  */
127 typedef struct {
128     /* all xdr'd */
129     MPI_Offset  nchars;
130     char       *cp;     /* [nchars+1] one additional char for '\0' */
131 } NC_string;
132 
133 extern NC *
134 ncmpii_new_NC(const MPI_Offset *chunkp);
135 
136 extern NC *
137 ncmpii_dup_NC(const NC *ref);
138 
139 /* Begin defined in string.c */
140 extern void
141 ncmpii_free_NC_string(NC_string *ncstrp);
142 
143 extern int
144 ncmpii_NC_check_name(const char *name, int file_ver);
145 
146 extern NC_string *
147 ncmpii_new_NC_string(size_t slen, const char *str);
148 
149 extern int
150 ncmpii_set_NC_string(NC_string *ncstrp, const char *str);
151 
152 /* End defined in string.c */
153 
154 /*
155  * NC dimension structure
156  */
157 typedef struct {
158     /* all xdr'd */
159     NC_string *name;
160     MPI_Offset size;
161 #ifdef ENABLE_SUBFILING
162     int range[2]; /* subfile range {start, end} */
163     MPI_Offset rcount; /* subfile range count */
164     int num_subfiles;
165 #endif
166 } NC_dim;
167 
168 #define NC_NAME_TABLE_CHUNK 16
169 #define HASH_TABLE_SIZE 256
170 /*
171 #define HASH_FUNC(x) ncmpii_jenkins_one_at_a_time_hash(x)
172 #define HASH_FUNC(x) ncmpii_additive_hash(x)
173 #define HASH_FUNC(x) ncmpii_rotating_hash(x)
174 #define HASH_FUNC(x) ncmpii_Pearson_hash(x)
175 */
176 #define HASH_FUNC(x) ncmpii_Bernstein_hash(x)
177 /* Look like Bernstein's hashing function performs the best */
178 
179 /* For the initial naive implementation of hashing:
180  * #define HASH_FUNC(x) (unsigned char)x[0]
181  * if used this simple hash function, HASH_TABLE_SIZE must be 256 which is the
182  * number of possible keys can be stored in an unsigned char
183  */
184 
185 typedef struct NC_nametable {
186     int  num;  /* number of elements added in the list array. Its value starts
187                   with zero and incremented with new name is created. When its
188                   value becomes a multiple of NC_NAME_TABLE_CHUNK, list will be
189                   reallocated to a space of size (num + NC_NAME_TABLE_CHUNK) */
190     int *list; /* dimension or variable IDs */
191 } NC_nametable;
192 
193 /* the dimension ID returned from ncmpi_def_dim() is an integer pointer
194  * which means the total number of defined dimension allowed in a file
195  * is up to 2^31-1. Thus, the member ndefined below should be of type int.
196  */
197 typedef struct NC_dimarray {
198     int            nalloc;        /* number allocated >= ndefined */
199     int            ndefined;      /* number of defined dimensions */
200     int            unlimited_id;  /* -1 for not defined, otherwise >= 0 */
201     NC_dim       **value;
202     NC_nametable   nameT[HASH_TABLE_SIZE]; /* table for quick name lookup.
203                     * indices 0, 1, ... HASH_TABLE_SIZE-1 are the hash keys.
204                     * nameT[i].num is the number of hash collisions. The IDs of
205                     * dimensions with names producing the same hash key i are
206                     * stored in nameT[i].list[*]
207                     */
208 } NC_dimarray;
209 
210 /* Begin defined in dim.c */
211 
212 extern void
213 ncmpii_free_NC_dim(NC_dim *dimp);
214 
215 extern NC_dim *
216 ncmpii_new_x_NC_dim(NC_string *name);
217 
218 extern int
219 ncmpii_find_NC_Udim(const NC_dimarray *ncap, NC_dim **dimpp);
220 
221 extern int
222 incr_NC_dimarray(NC_dimarray *ncap, NC_dim *newdimp);
223 
224 extern NC_dim*
225 dup_NC_dim(const NC_dim *dimp);
226 
227 /* dimarray */
228 
229 extern void
230 ncmpii_free_NC_dimarray(NC_dimarray *ncap);
231 
232 extern int
233 ncmpii_dup_NC_dimarray(NC_dimarray *ncap, const NC_dimarray *ref);
234 
235 extern NC_dim *
236 ncmpii_elem_NC_dimarray(const NC_dimarray *ncap, int elem);
237 
238 /* End defined in dim.c */
239 
240 /*
241  * NC attribute
242  *
243  * Number of attributes is limited by 2^31-1 because the argument attnump in
244  *  int nc_inq_attid(int ncid, int varid, const char *name, int *attnump);
245  * is a signed 4-byte integer.
246  */
247 typedef struct {
248     MPI_Offset xsz;      /* amount of space at xvalue (4-byte aligned) */
249     NC_string *name;     /* name of the attributes */
250     nc_type    type;     /* the discriminant */
251     MPI_Offset nelems;   /* number of attribute elements */
252     void      *xvalue;   /* the actual data, in external representation */
253 } NC_attr;
254 
255 typedef struct NC_attrarray {
256     int       nalloc;    /* number allocated >= ndefined */
257     int       ndefined;  /* number of defined attributes */
258     NC_attr **value;
259 } NC_attrarray;
260 
261 /* Begin defined in attr.c */
262 
263 extern void
264 ncmpii_free_NC_attr(NC_attr *attrp);
265 
266 extern NC_attr *
267 ncmpii_new_x_NC_attr(NC_string *strp, nc_type type, MPI_Offset nelems);
268 
269 extern int
270 incr_NC_attrarray(NC_attrarray *ncap, NC_attr *newelemp);
271 
272 extern NC_attr*
273 dup_NC_attr(const NC_attr *rattrp);
274 
275 extern int
276 ncmpii_NC_findattr(const NC_attrarray *ncap, const char *uname);
277 
278 /* attrarray */
279 
280 extern void
281 ncmpii_free_NC_attrarray(NC_attrarray *ncap);
282 
283 extern int
284 ncmpii_dup_NC_attrarray(NC_attrarray *ncap, const NC_attrarray *ref);
285 
286 extern NC_attr *
287 ncmpii_elem_NC_attrarray(const NC_attrarray *ncap, MPI_Offset elem);
288 
289 /* End defined in attr.c */
290 
291 /*
292  * NC variable: description and data
293  */
294 typedef struct {
295     int           xsz;    /* byte size of 1 array element */
296     MPI_Offset   *shape;  /* dim->size of each dim */
297     MPI_Offset   *dsizes; /* the right to left product of shape */
298     NC_string    *name;   /* name of the variable */
299     int           ndims;  /* number of dimensions */
300     int          *dimids; /* array of dimension IDs */
301     NC_attrarray  attrs;  /* attribute array */
302     nc_type       type;   /* variable's data type */
303     MPI_Offset    len;    /* this is the "vsize" defined in header format, the
304                              total size in bytes of the array variable.
305                              For record variable, this is the record size */
306     MPI_Offset    begin;  /* starting file offset of this variable */
307     char          no_fill;
308 #ifdef ENABLE_SUBFILING
309     int           ndims_org;  /* ndims before subfiling */
310     int          *dimids_org; /* dimids before subfiling */
311     int           num_subfiles;
312 #endif
313 } NC_var;
314 
315 /* note: we only allow less than 2^31-1 variables defined in a file */
316 typedef struct NC_vararray {
317     int            nalloc;      /* number allocated >= ndefined */
318     int            ndefined;    /* number of defined variables */
319     int            num_rec_vars;/* number of defined record variables */
320     NC_var       **value;
321     NC_nametable   nameT[HASH_TABLE_SIZE]; /* table for quick name lookup.
322                     * indices 0, 1, ... HASH_TABLE_SIZE-1 are the hash keys.
323                     * nameT[i].num is the number of hash collisions. The IDs of
324                     * variables with names producing the same hash key i are
325                     * stored in nameT[i].list[*]
326                     */
327 } NC_vararray;
328 
329 /* Begin defined in var.c */
330 
331 extern void
332 ncmpii_free_NC_var(NC_var *varp);
333 
334 extern NC_var *
335 ncmpii_new_x_NC_var(NC_string *strp, int ndims);
336 
337 extern NC_var*
338 dup_NC_var(const NC_var *rvarp);
339 
340 extern int
341 incr_NC_vararray(NC_vararray *ncap, NC_var *newvarp);
342 
343 /* vararray */
344 
345 extern void
346 ncmpii_free_NC_vararray(NC_vararray *ncap);
347 
348 extern int
349 ncmpii_dup_NC_vararray(NC_vararray *ncap, const NC_vararray *ref);
350 
351 extern int
352 ncmpii_NC_var_shape64(NC_var *varp, const NC_dimarray *dims);
353 
354 extern int
355 ncmpii_NC_check_vlen(NC_var *varp, MPI_Offset vlen_max);
356 
357 extern int
358 ncmpii_NC_lookupvar(NC *ncp, int varid, NC_var **varp);
359 
360 /* End defined in var.c */
361 
362 #define IS_RECVAR(vp) \
363         ((vp)->shape != NULL ? (*(vp)->shape == NC_UNLIMITED) : 0 )
364 
365 /*
366  *  The PnetCDF non-blocking I/O request type
367  */
368 typedef struct NC_req {
369     int            id;          /* even number for write, odd for read */
370     void          *buf;         /* the original user buffer */
371     void          *xbuf;        /* the buffer used to read/write, may point to
372                                    the same address as buf */
373     MPI_Offset     num_recs;    /* number of records requested (1 for
374                                    fixed-size variable) */
375     int            buftype_is_contig;
376     int            need_swap_back_buf;
377     int            abuf_index;  /* index in the abuf occupy_table
378                                    -1 means not using attached buffer */
379 
380     void          *tmpBuf;      /* tmp buffer to be freed, used only by
381                                    nonblocking varn when buftype is noncontig */
382     void          *userBuf;     /* user buffer to be unpacked from tmpBuf. used
383                                    only by by nonblocking varn when buftype is
384                                    noncontig */
385     NC_var        *varp;
386     MPI_Offset    *start;        /* [varp->ndims] */
387     MPI_Offset    *count;        /* [varp->ndims] */
388     MPI_Offset    *stride;       /* [varp->ndims] */
389     MPI_Offset     bnelems;      /* number of elements in user buffer */
390     MPI_Offset     offset_start; /* starting of aggregate access region */
391     MPI_Offset     offset_end;   /*   ending of aggregate access region */
392     MPI_Offset     bufcount;     /* the number of buftype in this request */
393     MPI_Datatype   buftype;      /* user defined derived data type */
394     MPI_Datatype   ptype;        /* element data type in buftype */
395     MPI_Datatype   imaptype;     /* derived data type constructed from imap */
396     int           *status;       /* pointer to user's status */
397 } NC_req;
398 
399 #define NC_ABUF_DEFAULT_TABLE_SIZE 128
400 
401 typedef struct NC_buf_status {
402     int        is_used;
403     MPI_Aint   buf_addr;
404     MPI_Offset req_size;
405 } NC_buf_status;
406 
407 typedef struct NC_buf {
408     MPI_Offset     size_allocated;
409     MPI_Offset     size_used;
410     int            table_size;
411     NC_buf_status *occupy_table; /* [table_size] */
412     int            tail;         /* index of last free entry */
413     void          *buf;
414 } NC_buf;
415 
416 /* chunk size for allocating read/write nonblocking request lists */
417 #define NC_REQUEST_CHUNK 1024
418 
419 struct NC {
420     /* linked list of currently opened netcdf files */
421     struct NC *next;
422     struct NC *prev;
423 #ifdef ENABLE_SUBFILING
424     int nc_num_subfiles; /* # of subfiles */
425     int ncid_sf; /* ncid of subfile */
426 #endif
427     /* contains the previous NC during redef. */
428     struct NC *old;
429     /* flags */
430 #define NC_INDEP  0x10000   /* in independent data mode, cleared by endindep */
431 #define NC_CREAT  0x20000   /* in create phase, cleared by enddef */
432 #define NC_INDEF  0x80000   /* in define mode, cleared by enddef */
433 #define NC_NSYNC  0x100000  /* synchronise numrecs on change */
434 #define NC_HSYNC  0x200000  /* synchronise whole header on change */
435 #define NC_NDIRTY 0x400000  /* numrecs has changed */
436 #define NC_HDIRTY 0x800000  /* header info has changed */
437 /* NC_NOFILL is defined in netcdf.h, historical interface */
438     int           format;   /* 1, 2, or 5 corresponding to CDF-1, 2, or 5 */
439     int           flags;
440     int           safe_mode;    /* 0 or 1, for parameter consistency check */
441     int           subfile_mode; /* 0 or 1, for disable/enable subfiling */
442     ncio         *nciop;
443     MPI_Offset    chunk;    /* largest extent this layer will request from
444                                ncio->get() */
445     MPI_Offset    xsz;      /* external size of this header, <= var[0].begin */
446     MPI_Offset    begin_var;/* file offset of the first (non-record) var */
447     MPI_Offset    begin_rec;/* file offset of the first 'record' */
448 
449     MPI_Offset    recsize;  /* length of 'record': sum of single record sizes
450                                of all the record variables */
451     MPI_Offset    numrecs;  /* number of 'records' allocated */
452     NC_dimarray   dims;     /* dimensions defined */
453     NC_attrarray  attrs;    /* global attributes defined */
454     NC_vararray   vars;     /* variables defined */
455     int           numGetReqs;  /* number of pending nonblocking get requests */
456     int           numPutReqs;  /* number of pending nonblocking put requests */
457     NC_req       *get_list;    /* list of nonblocking read requests */
458     NC_req       *put_list;    /* list of nonblocking write requests */
459     NC_buf       *abuf;        /* attached buffer, used by bput APIs */
460 };
461 
462 #define NC_readonly(ncp) \
463         (!fIsSet((ncp)->nciop->ioflags, NC_WRITE))
464 
465 #define NC_IsNew(ncp) \
466         fIsSet((ncp)->flags, NC_CREAT)
467 
468 #define NC_indep(ncp) \
469         fIsSet((ncp)->flags, NC_INDEP)
470 
471 #define NC_indef(ncp) \
472         (NC_IsNew(ncp) || fIsSet((ncp)->flags, NC_INDEF))
473 
474 #define set_NC_ndirty(ncp) \
475         fSet((ncp)->flags, NC_NDIRTY)
476 
477 #define NC_ndirty(ncp) \
478         fIsSet((ncp)->flags, NC_NDIRTY)
479 
480 #define set_NC_hdirty(ncp) \
481         fSet((ncp)->flags, NC_HDIRTY)
482 
483 #define NC_hdirty(ncp) \
484         fIsSet((ncp)->flags, NC_HDIRTY)
485 
486 #define NC_dofill(ncp) \
487         (!fIsSet((ncp)->flags, NC_NOFILL))
488 
489 #define NC_doFsync(ncp) \
490         fIsSet((ncp)->nciop->ioflags, NC_SHARE)
491 
492 #define NC_doHsync(ncp) \
493         fIsSet((ncp)->flags, NC_HSYNC)
494 
495 #define NC_doNsync(ncp) \
496         fIsSet((ncp)->flags, NC_NSYNC)
497 
498 #define NC_get_numrecs(ncp) \
499         ((ncp)->numrecs)
500 
501 #define NC_set_numrecs(ncp, nrecs) \
502         {((ncp)->numrecs = (nrecs));}
503 
504 #define NC_increase_numrecs(ncp, nrecs) \
505         {if((nrecs) > (ncp)->numrecs) ((ncp)->numrecs = (nrecs));}
506 
507 #define ErrIsHeaderDiff(err) \
508         (NC_EMULTIDEFINE_FIRST >= (err) && (err) >= NC_EMULTIDEFINE_LAST)
509 
510 #define IsPrimityMPIType(buftype) (buftype == MPI_FLOAT          || \
511                                    buftype == MPI_DOUBLE         || \
512                                    buftype == MPI_INT            || \
513                                    buftype == MPI_CHAR           || \
514                                    buftype == MPI_SIGNED_CHAR    || \
515                                    buftype == MPI_UNSIGNED_CHAR  || \
516                                    buftype == MPI_SHORT          || \
517                                    buftype == MPI_UNSIGNED_SHORT || \
518                                    buftype == MPI_UNSIGNED       || \
519                                    buftype == MPI_LONG           || \
520                                    buftype == MPI_LONG_LONG_INT  || \
521                                    buftype == MPI_UNSIGNED_LONG_LONG)
522 
523 /* Begin defined in nc.c */
524 
525 extern int
526 ncmpii_NC_check_id(int ncid, NC **ncpp);
527 
528 extern int
529 ncmpii_cktype(int cdf_ver, nc_type datatype);
530 
531 extern MPI_Offset
532 ncmpix_howmany(nc_type type, MPI_Offset xbufsize);
533 
534 extern int
535 ncmpii_dset_has_recvars(NC *ncp);
536 
537 extern int
538 ncmpii_write_header(NC *ncp);
539 
540 extern void
541 ncmpii_free_NC(NC *ncp);
542 
543 extern void
544 ncmpii_add_to_NCList(NC *ncp);
545 
546 extern void
547 ncmpii_del_from_NCList(NC *ncp);
548 
549 extern int
550 ncmpii_read_NC(NC *ncp);
551 
552 extern int
553 ncmpii_enddef(NC *ncp);
554 
555 extern int
556 ncmpii__enddef(NC *ncp, MPI_Offset h_minfree, MPI_Offset v_align,
557                MPI_Offset v_minfree, MPI_Offset r_align);
558 
559 extern int
560 ncmpii_close(NC *ncp);
561 
562 /* End defined in nc.c */
563 
564 #if 0
565 /* Begin defined in v1hpg.c */
566 
567 extern size_t
568 ncx_len_NC(const NC *ncp, MPI_Offset sizeof_off_t);
569 
570 extern int
571 ncx_put_NC(const NC *ncp, void **xpp, MPI_Offset offset, MPI_Offset extent);
572 
573 extern int
574 nc_get_NC( NC *ncp);
575 
576 /* End defined in v1hpg.c */
577 
578 /* Begin defined in putget.c */
579 
580 extern int
581 ncmpii_fill_NC_var(NC *ncp, const NC_var *varp, MPI_Offset recno);
582 
583 extern int
584 ncmpii_inq_rec(int ncid, MPI_Offset *nrecvars, MPI_Offset *recvarids, MPI_Offset *recsizes);
585 
586 extern int
587 ncmpii_get_rec(int ncid, MPI_Offset recnum, void **datap);
588 
589 extern int
590 ncmpii_put_rec(int ncid, MPI_Offset recnum, void *const *datap);
591 #endif
592 
593 /* End defined in putget.c */
594 
595 /* Begin defined in header.c */
596 typedef struct bufferinfo {
597     ncio       *nciop;
598     MPI_Offset  offset;   /* current read/write offset in the file */
599     int         version;  /* 1, 2, and 5 for CDF-1, 2, and 5 respectively */
600     int         safe_mode;/* 0: disabled, 1: enabled */
601     void       *base;     /* beginning of read/write buffer */
602     void       *pos;      /* current position in buffer */
603     MPI_Offset  size;     /* size of the buffer */
604     MPI_Offset  index;    /* index of current position in buffer */
605 } bufferinfo;
606 
607 extern int
608 ncmpix_len_nctype(nc_type type);
609 
610 #if 0
611 extern int
612 hdr_put_NC_attrarray(bufferinfo *pbp, const NC_attrarray *ncap);
613 #endif
614 
615 extern MPI_Offset
616 ncmpii_hdr_len_NC(const NC *ncp);
617 
618 extern int
619 ncmpii_hdr_get_NC(NC *ncp);
620 
621 extern int
622 ncmpii_hdr_put_NC(NC *ncp, void *buf);
623 
624 extern int
625 ncmpii_NC_computeshapes(NC *ncp);
626 
627 extern int
628 ncmpii_hdr_check_NC(bufferinfo *getbuf, NC *ncp);
629 /* end defined in header.c */
630 
631 /* begin defined in mpincio.c */
632 extern int
633 ncmpiio_create(MPI_Comm comm, const char *path, int ioflags, MPI_Info info,
634                NC *ncp);
635 
636 extern int
637 ncmpiio_open(MPI_Comm comm, const char *path, int ioflags, MPI_Info info,
638              NC *ncp);
639 extern int
640 ncmpiio_sync(ncio *nciop);
641 
642 extern int
643 ncmpiio_move(ncio *const nciop, MPI_Offset to, MPI_Offset from,
644              MPI_Offset nbytes);
645 
646 extern int
647 ncmpiio_move_fixed_vars(NC *ncp, NC *old);
648 
649 extern int
650 ncmpiio_get_hint(NC *ncp, char *key, char *value, int *flag);
651 
652 extern int
653 NC_computeshapes(NC *ncp);
654 
655 /* end defined in mpincio.h */
656 
657 /* begin defined in error.c */
658 
659 int ncmpii_handle_error(int mpi_errorcode, char *msg);
660 
661 /* end defined in error.c */
662 /*
663  * These functions are used to support
664  * interface version 2 backward compatibility.
665  * N.B. these are tested in ../nc_test even though they are
666  * not public. So, be careful to change the declarations in
667  * ../nc_test/tests.h if you change these.
668  */
669 
670 int ncmpii_x_putn_NC_CHAR  (void *xbuf, const void *buf, MPI_Offset nelems,
671                            MPI_Datatype datatype);
672 int ncmpii_x_putn_NC_BYTE  (int cdf_ver,
673                            void *xbuf, const void *buf, MPI_Offset nelems,
674                            MPI_Datatype datatype, void *fillp);
675 int ncmpii_x_putn_NC_UBYTE (void *xbuf, const void *buf, MPI_Offset nelems,
676                            MPI_Datatype datatype, void *fillp);
677 int ncmpii_x_putn_NC_SHORT (void *xbuf, const void *buf, MPI_Offset nelems,
678                            MPI_Datatype datatype, void *fillp);
679 int ncmpii_x_putn_NC_USHORT(void *xbuf, const void *buf, MPI_Offset nelems,
680                            MPI_Datatype datatype, void *fillp);
681 int ncmpii_x_putn_NC_INT   (void *xbuf, const void *buf, MPI_Offset nelems,
682                            MPI_Datatype datatype, void *fillp);
683 int ncmpii_x_putn_NC_UINT  (void *xbuf, const void *buf, MPI_Offset nelems,
684                            MPI_Datatype datatype, void *fillp);
685 int ncmpii_x_putn_NC_FLOAT (void *xbuf, const void *buf, MPI_Offset nelems,
686                            MPI_Datatype datatype, void *fillp);
687 int ncmpii_x_putn_NC_DOUBLE(void *xbuf, const void *buf, MPI_Offset nelems,
688                            MPI_Datatype datatype, void *fillp);
689 int ncmpii_x_putn_NC_INT64 (void *xbuf, const void *buf, MPI_Offset nelems,
690                            MPI_Datatype datatype, void *fillp);
691 int ncmpii_x_putn_NC_UINT64(void *xbuf, const void *buf, MPI_Offset nelems,
692                            MPI_Datatype datatype, void *fillp);
693 
694 int ncmpii_x_getn_NC_CHAR  (const void *xbuf, void *buf, MPI_Offset nelems,
695                            MPI_Datatype datatype);
696 int ncmpii_x_getn_NC_BYTE  (int cdf_ver,
697                            const void *xbuf, void *buf, MPI_Offset nelems,
698                            MPI_Datatype datatype);
699 int ncmpii_x_getn_NC_UBYTE (const void *xbuf, void *buf, MPI_Offset nelems,
700                            MPI_Datatype datatype);
701 int ncmpii_x_getn_NC_SHORT (const void *xbuf, void *buf, MPI_Offset nelems,
702                            MPI_Datatype datatype);
703 int ncmpii_x_getn_NC_USHORT(const void *xbuf, void *buf, MPI_Offset nelems,
704                            MPI_Datatype datatype);
705 int ncmpii_x_getn_NC_INT   (const void *xbuf, void *buf, MPI_Offset nelems,
706                            MPI_Datatype datatype);
707 int ncmpii_x_getn_NC_UINT  (const void *xbuf, void *buf, MPI_Offset nelems,
708                            MPI_Datatype datatype);
709 int ncmpii_x_getn_NC_FLOAT (const void *xbuf, void *buf, MPI_Offset nelems,
710                            MPI_Datatype datatype);
711 int ncmpii_x_getn_NC_DOUBLE(const void *xbuf, void *buf, MPI_Offset nelems,
712                            MPI_Datatype datatype);
713 int ncmpii_x_getn_NC_INT64 (const void *xbuf, void *buf, MPI_Offset nelems,
714                            MPI_Datatype datatype);
715 int ncmpii_x_getn_NC_UINT64(const void *xbuf, void *buf, MPI_Offset nelems,
716                            MPI_Datatype datatype);
717 
718 int NC_start_count_stride_ck(const NC *ncp, const NC_var *varp,
719                 const MPI_Offset *start, const MPI_Offset *count,
720                 const MPI_Offset *stride, const int rw_flag);
721 
722 int ncmpii_need_convert(int format, nc_type nctype, MPI_Datatype mpitype);
723 
724 int ncmpii_need_swap(nc_type nctype,MPI_Datatype mpitype);
725 
726 void ncmpii_swapn(void *dest_p, const void* src_p, MPI_Offset nelems, int esize);
727 
728 void ncmpii_in_swapn(void *buf, MPI_Offset nelems, int esize);
729 
730 int ncmpii_is_request_contiguous(NC *ncp, NC_var *varp,
731                 const MPI_Offset starts[], const MPI_Offset  counts[]);
732 
733 int ncmpii_get_offset(NC *ncp, NC_var *varp, const MPI_Offset starts[],
734                 const MPI_Offset counts[], const MPI_Offset strides[],
735                 const int rw_flag, MPI_Offset *offset_ptr);
736 
737 int ncmpii_check_mpifh(NC* ncp, int collective);
738 
739 int ncmpii_write_numrecs(NC *ncp, MPI_Offset new_numrecs);
740 
741 int ncmpii_sync_numrecs(NC *ncp, MPI_Offset newnumrecs);
742 
743 int ncmpii_vars_create_filetype(NC* ncp, NC_var* varp,
744                 const MPI_Offset start[], const MPI_Offset count[],
745                 const MPI_Offset stride[], int rw_flag, int *blocklen,
746                 MPI_Offset *offset, MPI_Datatype *filetype,
747                 int *is_filetype_contig);
748 
749 extern int
750 ncmpii_igetput_varm(NC *ncp, NC_var *varp, const MPI_Offset *start,
751                 const MPI_Offset *stride, const MPI_Offset *imap,
752                 const MPI_Offset *count, void *buf, MPI_Offset bufcount,
753                 MPI_Datatype datatype, int *reqid, int rw_flag, int use_abuf,
754                 int isSameGroup);
755 
756 extern int
757 ncmpii_wait(NC *ncp, int io_method, int num_reqs, int *req_ids,
758                 int *statuses);
759 
760 extern int
761 ncmpii_cancel(NC *ncp, int num_req, int *req_ids, int *statuses);
762 
763 extern int
764 ncmpii_inq_malloc_size(MPI_Offset *size);
765 
766 extern int
767 ncmpii_inq_malloc_max_size(MPI_Offset *size);
768 
769 extern int
770 ncmpii_inq_malloc_list(void);
771 
772 #ifdef PNC_MALLOC_TRACE
773 void ncmpii_init_malloc_tracing(void);
774 #endif
775 
776 extern void *
777 NCI_Malloc_fn(size_t size, const int lineno, const char *func,
778               const char *filename);
779 
780 extern void *
781 NCI_Calloc_fn(size_t nelem, size_t elsize, const int lineno, const char *func,
782               const char *filename);
783 
784 extern void *
785 NCI_Realloc_fn(void *ptr, size_t size, const int lineno, const char *func,
786                const char *filename);
787 
788 extern void
789 NCI_Free_fn(void *ptr, const int lineno, const char *func,
790             const char *filename);
791 
792 extern int
793 ncmpii_inq_files_opened(int *num, int *ncids);
794 
795 extern MPI_Datatype
796 ncmpii_nc2mpitype(nc_type type);
797 
798 extern nc_type
799 ncmpii_mpi2nctype(MPI_Datatype itype);
800 
801 extern int
802 ncmpii_end_indep_data(NC *ncp);
803 
804 extern int
805 ncmpii_file_set_view(NC *ncp, MPI_File fh, MPI_Offset *offset, MPI_Datatype filetype);
806 
807 extern int
808 ncmpii_create_imaptype(NC_var *varp, const MPI_Offset *count,
809                        const MPI_Offset *imap, const MPI_Offset  bnelems,
810                        const int el_size, MPI_Datatype ptype,
811                        MPI_Datatype *imaptype);
812 
813 extern int
814 ncmpii_calc_datatype_elems(NC_var *varp, const MPI_Offset *count,
815                            MPI_Datatype buftype,
816                            MPI_Datatype *ptype, MPI_Offset *bufcount,
817                            MPI_Offset *bnelems, MPI_Offset *nbytes,
818                            int *el_size, int *buftype_is_contig);
819 
820 extern int
821 ncmpii_fill_vars(NC *ncp);
822 
823 extern int
824 ncmpii_sanity_check(int ncid, int varid, const MPI_Offset *start,
825                     const MPI_Offset *count, const MPI_Offset *stride,
826                     MPI_Offset bufcount, MPI_Datatype buftype,
827                     enum API_KIND api, int isFlexibleAPI, int mustInDataMode,
828                     int rw_flag, int io_method, NC **ncp, NC_var **varp);
829 
830 extern char*
831 ncmpii_err_code_name(int err);
832 
833 extern int
834 ncmpii_jenkins_one_at_a_time_hash(const char *str_name);
835 
836 extern int
837 ncmpii_additive_hash(const char *str_name);
838 
839 extern int
840 ncmpii_rotating_hash(const char *str_name);
841 
842 extern int
843 ncmpii_Bernstein_hash(const char *str_name);
844 
845 extern int
846 ncmpii_Pearson_hash(const char *str_name);
847 
848 extern int
849 ncmpii_update_name_lookup_table(NC_nametable *nameT, const int id,
850                                 const char *oldname, const char *newname);
851 
852 extern int
853 ncmpii_inq_var_fill(NC_var *varp, void *fill_value);
854 
855 extern int
856 ncmpii_inq_default_fill_value(int type, void *fill_value);
857 
858 extern int
859 ncmpii_getput_zero_req(NC *ncp, int rw_flag);
860 
861 #endif /* _NC_H_ */
862